web-dev-qa-db-ja.com

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

このコードがあるとき

$.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

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

$.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があるべきときのOPTIONSとは何ですか?そして、私のcontent-typeはどこでapplication/jsonに設定されていますか?そして、リクエストパラメータは何らかの理由でなくなりました。

PDATE 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;
    }
}

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

PDATE 2

そんなに長い間答えないですみません。

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

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

それは助けにはならなかった、私は持っている---私は持っている方法は許されないサーバーからのエラー。

これは私のフィドラーが言うことです

enter image description here

だから、今私は私のサーバーがPOST、GET、OPTIONSを受け付けることを確認することができます(レスポンスヘッダが期待通りに動くのなら)。しかし、なぜ「方法は許されない」のでしょうか。

サーバーからのWebViewレスポンス(上の画像でRawレスポンスを確認できます)では、次のようになります。

enter image description here

92

Urlオプションからhttp://を削除すると、正しい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()、FirefoxでREQUEST_METHODとして "OPTIONS"を送信している$ .post

編集:もう少し調べたところ、発信元ドメインからの要求が許可されているかどうかを調べるためにOPTIONSヘッダーが使用されていました。 fiddlerを使って、私は自分のサーバーからのレスポンスヘッダに以下を追加しました。

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

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

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);
  }
});​

参考文献:

81
Mike Wade

私がそれをどのように使ったかをあなたに示すことができます

  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;
                }
            }
        });
    }
34
Amritpal Singh

したがって、これを機能させるために必要なのは、addだけです。

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

投稿リクエストのフィールドとして使用するとうまくいきます。

9
Cody Jacques

私はそれらのスクリーンを認識しました、私はCodeFluentEntitiesを使用しています、そして私も私のために働く解決策を得ました。

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

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

ご覧のとおり、私が使っているなら

contentType: "",

または

contentType: "text/plain", //chrome

すべてうまくいきます。

私はヘッダーも変更したので、それがあなたが必要とするすべてであるという100%の確信はありません。

4
Alexey Avdeyev

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

正常に動作します。 AndréPedrosoありがとうございます。 :-)

2
Fanda

あなたがこれを使うならば:

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) { }
  }
)

私は同じ問題を抱えていました。私はjbossサーバー上でJava restアプリを実行しています。しかし、その解決策はASP .NET Webアプリケーションでも同様であると思います。

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

これは、クロスドメイン呼び出しを実行しているときにのみ発生します。あなたのケースでは、同じドメインのURLパスを呼び出す代わりに 'http://localhost:16329/Hello'を呼び出す '/ Hello'

あなたがクロスドメイン呼び出しをするつもりならあなたは注釈付きのメソッドであなたの休息サービスクラスを強化しなければなりません "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")
1
Vincent

私はjquery ajaxを介してPOST requestで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 );
      });


        });
    });

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

0
Rahul Aparajit