jQuery.ajaxでcontent-typeを 'application / json'に設定できません


106

このコードがあるとき

$.ajax({
    type: 'POST',
    //contentType: "application/json",
    url: 'http://localhost:16329/Hello',
    data: { name: 'norm' },
    dataType: 'json'
});

フィドラーで私は次の生の要求を見ることができます

POST http://localhost:16329/Hello HTTP/1.1
Host: localhost:16329
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://localhost:14693/WebSite1/index.html
Content-Length: 9
Origin: http://localhost:14693
Pragma: no-cache
Cache-Control: no-cache

name=norm

しかし、私が試みているのは、content-typeをapplication / x-www-form-urlencodedからapplication / jsonに設定することです。しかし、このコード

$.ajax({
    type: "POST",
    contentType: "application/json",
    url: 'http://localhost:16329/Hello',
    data: { name: 'norm' },
    dataType: "json"
});

奇妙なリクエストを生成します(Fiddlerで確認できます)

OPTIONS http://localhost:16329/Hello HTTP/1.1
Host: localhost:16329
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Origin: http://localhost:14693
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Pragma: no-cache
Cache-Control: no-cache

何故ですか?そこにPOSTすべきときのオプションとは何ですか?そして、私のコンテンツタイプはどこにapplication / jsonに設定されていますか?リクエストパラメータが何らかの理由でなくなっています。

アップデート1

サーバー側には、本当にシンプルなRESTfulサービスがあります。

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class RestfulService : IRestfulService
{
    [WebInvoke(
        Method = "POST",
        UriTemplate = "Hello",
        ResponseFormat = WebMessageFormat.Json)]
    public string HelloWorld(string name)
    {
        return "hello, " + name;
    }
}

しかし、何らかの理由で、このメソッドをパラメーターで呼び出すことができません。

アップデート2

長く答えられなかったのでごめんなさい。

これらのヘッダーをサーバーの応答に追加しました

 Access-Control-Allow-Origin: *
 Access-Control-Allow-Headers: Content-Type
 Access-Control-Allow-Methods: POST, GET, OPTIONS

それは役に立たなかった、私はサーバーからのメソッドを許可されいないエラーがあります。

これが私のバイオリン奏者の発言です

ここに画像の説明を入力してください

これで、サーバーがPOST、GET、OPTIONSを確実に受け入れるようになりました(応答ヘッダーが期待どおりに機能する場合)。しかし、なぜ「許可されていない方法」なのでしょうか。

サーバーからのWebView応答では(上の図のRaw応答を見ることができます)は次のようになります

ここに画像の説明を入力してください


2
JSON.stringfy()メソッドを試してください
Amritpal Singh

ここを見て。これは非常によく私の作品:stackoverflow.com/questions/9754767/...
Fanda

私はまったく同じ問題を抱えていますが、NodeJSをバックエンドとして使用しています。また、すべてのOPTION要求が受け入れられるだけでなく、すべてのOPTION要求に200応答を強制するように設定して、残りの請願が期待どおりに機能するようにします応答なし...
HeberLZ 2014年

1
こんにちは@VitaliiKorsakov。問題を解決しましたか?同じ問題、つまりcontentTypeを変更できません。
ワールドターミネーター2014

1
私は同じ問題を抱えてそれを機能させました..解決策はこのページの答えにあります:stackoverflow.com/questions/20295080/… ..要約すると: "contentType: 'application / json'を使用すると、 $ _POSTが入力されていることに依存することはできません。$ _ POSTはフォームエンコードされたコンテンツタイプに対してのみ入力されます。そのため、PHPのraw入力からデータを読み取る必要があります。..サーバーでphpを使用していないようです側ではありますが、この情報が何らかの形で役立つことを願っています。
サラ、

回答:


91

http://urlオプションから削除すると、正しいHTTP POSTヘッダーが送信されるようになります。

ホスト名を完全に修飾する必要はないと思います。以下のように相対URLを使用してください。

   $.ajax({
      type: "POST",
      contentType: "application/json",
      url: '/Hello',
      data: { name: 'norm' },
      dataType: "json"
   });

うまくいく私の例:

        $.ajax({
            type: "POST",
            url: siteRoot + "api/SpaceGame/AddPlayer",
            async: false,
            data: JSON.stringify({ Name: playersShip.name, Credits: playersShip.credits }),
            contentType: "application/json",
            complete: function (data) {
            console.log(data);
            wait = false;
        }
    });

おそらく関連: jQuery $ .ajax()、$。postがFirefoxでREQUEST_METHODとして「OPTIONS」を送信

編集: さらに調査した後、OPTIONSヘッダーを使用して、発信元ドメインからの要求が許可されているかどうかを確認しました。fiddlerを使用して、サーバーの応答ヘッダーに以下を追加しました。

 Access-Control-Allow-Origin: *
 Access-Control-Allow-Headers: Content-Type
 Access-Control-Allow-Methods: POST, GET, OPTIONS

ブラウザーがこの応答を受信すると、jsonデータを含む正しいPOST要求を送信します。デフォルトのform-urlencodedコンテンツタイプは安全であると考えられるため、余分なクロスドメインチェックを受けません。

前述のヘッダーをOPTIONSリクエストへのサーバー応答に追加する必要があるようです。もちろん、すべてではなく特定のドメインからのリクエストを許可するように設定する必要があります。

これをテストするために、次のjQueryを使用しました。

$.ajax({
   type: "POST",
   url: "http://myDomain.com/path/AddPlayer",
   data: JSON.stringify({
      Name: "Test",
       Credits: 0
   }),
   //contentType: "application/json",
   dataType: 'json',
   complete: function(data) {
       $("content").html(data);
  }
});​

参照:


クライアントとサーバー間の結合を緩めたいです。サーバーはRESTfulサービスであり、このサービスのすべてのクライアントはサーバーへのURLを知っている必要があります。
Vitalii Korsakov

この質問のシナリオについて、あなたの投稿でいくつかの詳細を提供できますか?クライアントが異なるドメイン上にある場合、同じオリジンの問題が発生する可能性があります。
マイクウェイド

サーバーサイドに関する追加情報を投稿しました。現在サーバーとクライアントの両方がローカルホスト上にありますが、ポートが異なります。後でそれらはおそらく別のドメイン上にあります。
Vitalii Korsakov

発生している問題は同じオリジンポリシーで発生しているようです。これらのリンク関連の質問に加えて、jsonpと私の回答でリンクした質問を確認する価値があるかもしれません。jqueryクロスドメインガイド -クロスドメインリクエストの経験はあまりありませんが、これらのリンクが役立つことを願っています。
マイクウェイド

パラメータを渡さずにcontent-typeがapplication / x-www-form-urlencodedである場合はすべて正常に機能するため、これは問題だとは思いません。しかし、パラメーターを渡すことができなかった場合、POSTリクエストは必要ありません。
Vitalii Korsakov

41

使い方をお見せします

  function GetDenierValue() {
        var denierid = $("#productDenierid").val() == '' ? 0 : $("#productDenierid").val();
        var param = { 'productDenierid': denierid };
        $.ajax({
            url: "/Admin/ProductComposition/GetDenierValue",
            dataType: "json",
            contentType: "application/json;charset=utf-8",
            type: "POST",
            data: JSON.stringify(param),
            success: function (msg) {
                if (msg != null) {
                    return msg.URL;
                }
            }
        });
    }

次の答えと同じです。すべてのサービス機能がホストされているサーバーのURLを指定することはできません
Vitalii Korsakov

@VitaliiKorsakov私は去りました、あなたの問題を整理してくれませんか。
Amritpal Singh 2012

答えてくれてありがとう!これがどこかで書かれていないとは信じられません。指定したタイプが「json」の場合、JQueryはjsonをポストするようですが、そうではありません...
Jason Goemaat

1
@JasonGoemaat jQueryのdataTypeパラメーターは、返された応答の本文を解析するためにのみ使用されます。ドキュメンテーションを読むと、それは必要さえないことがわかります。dataTypeのデフォルト値はインテリジェントな推測です。あなたの問題は、jqueryのデータ属性が構成可能ではないことです。jqueryがデータオブジェクトをどのように解析するかはわかりません。そのため、以前にjsonをシリアル化する必要があります。jQueryのURLのみ-フォームエンコードにシリアライズため
ロイック・フォーレ-ラクロワ

12

したがって、これが機能するために必要なことは、次の追加だけです。

headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
}

あなたの投稿リクエストへのフィールドとして、それは動作します。


api.jquery.com/jquery.ajax ドキュメントを見ると、指定しないとデフォルトで 'application / x-www-form-urlencoded;と表示されます。charset = UTF-8 '(これが原因です。contentTypeを設定するだけでは機能しないのはなぜですか。使用しているjQueryのバージョンを確認し、古いバージョンの場合は更新することをお勧めします)。
Cody Jacques

これは機能していません。持っていますがtype: "POST"、出品中OPTIONSです。
user9645 2017

5

私はそれらの画面を認識し、CodeFluentEntitiesを使用しており、私にとっても機能するソリューションを持っています。

私はその構造を使用しています:

$.ajax({
   url: path,
   type: "POST",
   contentType: "text/plain",
   data: {"some":"some"}
}

あなたが見ることができるように、私が使うなら

contentType: "",

または

contentType: "text/plain", //chrome

すべてが正常に動作します。

ヘッダーが変更されているため、必要なものがすべてかどうかは100%わかりません。


5

これを使用する場合:

contentType: "application/json"

AJAXはGETまたはPOSTパラメータをサーバーに送信しません。理由は不明です。

今日それを習得するのに何時間もかかりました。

ただ使用する:

$.ajax(
  { url : 'http://blabla.com/wsGetReport.php',
    data : myFormData, type : 'POST', dataType : 'json', 
    // contentType: "application/json", 
    success : function(wsQuery) { }
  }
)

1
残念ながら私にとって正しい答えです。contentTypeを省略し、dataTypeを使用して、多くのサービスが適切に実装しないCORS OPTIONSガベージをバイパスします。とても迷惑。
Umopepisdn 2018

2

ここでこの問題の解決策を見つけました。IISアプリサービスハンドラーで動詞OPTIONSを許可することを忘れないでください。

正常に動作します。アンドレペドロソに感謝します。:-)


1

同じ問題がありました。私はjbossサーバーでJava RESTアプリを実行しています。しかし、私はソリューションがASP .NET Webアプリケーションで同様であると思います。

Firefoxは、サーバー/レストURLに対して事前呼び出しを行い、許可されているオプションを確認します。これは、サーバーがそれに応じて応答しない「OPTIONS」リクエストです。このOPTIONS呼び出しが正しく応答されると、jsonコンテンツを含む実際の「POST」要求である2番目の呼び出しが実行されます。

これは、クロスドメインコールを実行するときにのみ発生します。http://localhost:16329/Hello同じドメイン '/ Hello'の下のURLパスを呼び出す代わりに' 'を呼び出す場合

クロスドメインコールを行う場合は、注釈付きのメソッドで残りのサービスクラスを拡張する必要があります。このメソッドは、「OPTIONS」httpリクエストをサポートしています。これは、対応するJava実装です。

@Path("/rest")
public class RestfulService {

    @POST
    @Path("/Hello")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.TEXT_PLAIN)
    public string HelloWorld(string name)
    {
        return "hello, " + name;
    }

//THIS NEEDS TO BE ADDED ADDITIONALLY IF MAKING CROSS-DOMAIN CALLS

    @OPTIONS
    @Path("/Hello")
    @Produces(MediaType.TEXT_PLAIN+ ";charset=utf-8")
    public Response checkOptions(){
        return Response.status(200)
        .header("Access-Control-Allow-Origin", "*")
        .header("Access-Control-Allow-Headers", "Content-Type")
        .header("Access-Control-Allow-Methods", "POST, OPTIONS") //CAN BE ENHANCED WITH OTHER HTTP CALL METHODS 
        .build();
    }
}

だから私は.NETで注釈が付けられた追加のメソッドを追加する必要があると思います

[WebInvoke(
        Method = "OPTIONS",
        UriTemplate = "Hello",
        ResponseFormat = WebMessageFormat.)]

次のヘッダーが設定されている場所

.header("Access-Control-Allow-Origin", "*")
        .header("Access-Control-Allow-Headers", "Content-Type")
        .header("Access-Control-Allow-Methods", "POST, OPTIONS")

0

jquery ajaxを介してPOSTリクエストでJSONデータを送信するためのソリューションを得ました。以下のコードを使用しました

    var data = new Object();
    data.p_clientId = 4;
    data =  JSON.stringify(data);

    $.ajax({
      method: "POST",
      url: "http://192.168.1.141:8090/api/Client_Add",
      data: data,
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'text/plain'
    }
    })
      .done(function( msg ) {
        alert( "Data Saved: " + msg );
      });


        });
    });

'Content-Type': 'text/plain'ヘッダーで生のJSONデータを送信するために使用しました。OPTIONに変換されたリクエストメソッド
を使用してもContent-Type: 'application/json'、メソッドを使用しても変換されContent-Type: 'test/plain'ず、POSTのままになるためです。うまくいけば、これは誰かを助けるでしょう。


3
実際にはOPTIONに変換するのではなく、POSTが許可されているかどうかを確認するCORSプリフライトリクエストを送信しています。これが正しく戻らない場合、POSTは発生しません。
Umopepisdn 2018

0

こんにちはこれらの2つの行は私のために働いた。

contentType: "application / json; charset = utf-8"、dataType: "json"

 $.ajax({
            type: "POST",
            url: "/v1/candidates",
            data: obj,
            **contentType:"application/json; charset=utf-8",
            dataType:"json",**
            success: function (data) {
                table.row.add([
                    data.name, data.title
                ]).draw(false);
            }

ありがとう、Prashant

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.