jquery-$ .post()でcontentType = application / jsonを使用する方法


309

$ .post()をjqueryで使用する場合、デフォルトのcontentTypeがapplication / x-www-form-urlencodedであることに気づきました-私のasp.net mvcコードにcontentType = application / jsonが必要な場合

(application / jsonを使用する必要がある理由については、この質問を参照してください。ASPNETMVC-ModelState.IsValidがfalseである理由は、そのフィールドに値があるのに「xフィールドが必要」なのですか?

$ .post()にcontentType = application / jsonを送信させるにはどうすればよいですか?$ .post()関数がすでにたくさんあるので、時間がかかりすぎるので$ .ajax()に変更したくありません。

私がしようとすると

$.post(url, data, function(), "json") 

まだcontentType = application / x-www-form-urlencodedが含まれています。では、コンテンツタイプをjsonに変更しない場合、「json」パラメータは正確に何をするのでしょうか。

私がしようとすると

$.ajaxSetup({
  contentType: "application/json; charset=utf-8"
});

それは機能しますが、私が持っているすべての$ .getと$ .postに影響を及ぼし、いくつかを壊します。

では、$。post()の動作を変更してcontentType = application / jsonを送信する方法はありますか?

回答:


71

私はあなたがしなければならないかもしれないと思う

1.ソースを変更して、$。postが常にJSONデータタイプを使用するようにし$.ajaxます

または

2. 使用する構成のショートカットである独自のユーティリティ関数を定義します$.ajax

または

3. $.post functionモンキーパッチを介して独自の実装で上書きすることができます。

この例のJSONデータ型は、サーバーから返さたデータ型を参照しており、サーバーに送信された形式を参照していません。


5
+1、私は新しいメソッドまたは上書きjQuery.postメソッドを定義するために行きます、それは本当にシンプルな関数です...
CMS

3
これは悪い考えではありません。$。postと同じ(リンクされたコードをコピーする)ことと、コンテンツタイプを変更する$ .mvcpost()というメソッドを作成するだけです。次に、変更が必要なすべての$ .post()について、前に3文字追加する必要があります。それらを$ .ajax()として書き換えるよりもはるかに高速です。
JK。

9
@PavelRepin、ペイロードでJSON.stringify()を呼び出す必要がありました。
Ustaman Sangat 2012

2
@dragon-「contentType = application / jsonを送信するために$ .post()の動作を変更できる方法はありますか?」に対する3つの解決策があります。答えではない部分はどこですか?
Russ Cam

2
また、知っておくことが重要です。$。ajaxとさまざまなメソッドは、指定されたデータに基づいて、(指定されていない限り)contentTypeが何であるかを推測しようとします。"mystring data"なりますapplication/x-www-form-urlencoded;ようにオブジェクトはどこ{ anyKey: "anyvalue and type" }になりますapplication/json。jsonを読み取る多くのサーバーは、文字列ではなくオブジェクトまたは配列のみを許可します。そのため、jqueryはこのように予測します。オブジェクトにラップされずに文字列や数値などを読み取るサーバーがある場合は、この回答のようにcontent-typeを指定する必要があります。
bzuillsmith 14

395
$.ajax({
  url:url,
  type:"POST",
  data:data,
  contentType:"application/json; charset=utf-8",
  dataType:"json",
  success: function(){
    ...
  }
})

参照:jQuery.ajax()


13
元の投稿では、「$。post()の動作を変更してcontentType = application / jsonを送信する方法はありますか?」しかし、それはまた「それは機能しますが、私が持っているすべての$ .getと$ .postに影響を及ぼし、いくつかを壊します」とも述べています。「$ .postを使用するのと同じことをどのようにして実現できますか?他の$ .getと$ .postを壊すことなく正しいcontentTypeを送信するにはどうすればよいですか」という質問を理解しています。それは間違っていますか?
エイドリアン

5
@ x1a4は明らかに.ajaxがajaxSetupではなく呼び出しであることを理解していません
Walker

39
@ Adrien、2年後の価値はありますが、これをグーグル検索したときに私が探していた答えはあなたのものです。
AwesomeTown

74
JSON.stringify(data)サーバーはJSON文字列を期待し、jQueryはアンパサンド(form-urlencoded)を使用してキーと値のペアを単純に連結するため、を使用する必要がありました。
ドラゴン

3
4年後でも、この答えは10行未満のコードで私の検索時間を解決しました。
Pieter VDE、2014

86

最後に私は解決策を見つけました、それは私のために働きます:

jQuery.ajax ({
    url: myurl,
    type: "POST",
    data: JSON.stringify({data:"test"}),
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    success: function(){
        //
    }
});

8
エラーが発生し続ける理由を理解できませんでした。データを文字列化する必要があります。
zastrowm

5
私はこれが機能することを知っていますが、なぜああ、なぜあなたは文字列化する必要があるのですか?それはjQueryのバグですか?data引数をにシリアル化してもまったく問題x-www-form-urlencodedないようですが、リクエストのコンテンツタイプがJSONであると指定した場合でもdata、不一致な形式で送信するよう要求します。
Pavel Repin

上手。あまり掘らなかった。それが機能していて嬉しかったです。;)私のサーバーにはJSONが必要です。
vvkatwss vvkatwss

こっちも一緒。JSON.stringifyがないと機能しません。なぜでしょうか。
John Simoes 2014年

42

スクリプトの次のメソッドをjQueryに追加しました。

jQuery["postJSON"] = function( url, data, callback ) {
    // shift arguments if data argument was omitted
    if ( jQuery.isFunction( data ) ) {
        callback = data;
        data = undefined;
    }

    return jQuery.ajax({
        url: url,
        type: "POST",
        contentType:"application/json; charset=utf-8",
        dataType: "json",
        data: data,
        success: callback
    });
};

そしてそれを使うには

$.postJSON('http://url', {data: 'goes', here: 'yey'}, function (data, status, xhr) {
    alert('Nailed it!')
});

これは、元のJQueryソースから「get」と「post」のコードをコピーし、いくつかのパラメーターをハードコーディングしてJSON POSTを強制することで行われました。

ありがとう!


2
いつものように-最良の答えはパーティーの最後に来て、賛成票が最も少なくなります;(
nikib3ro

すばらしい答えです。$。postがこれを「そのまま」実行しないことを理解するにはしばらく時間がかかります。
markp3rry 2014年

21

ただ使う

jQuery.ajax ({
    url: myurl,
    type: "POST",
    data: mydata,
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    success: function(){
        //
    }
});

更新された @JK:$ .postを使用して1つのコード例のみを質問に書き込んだ場合、回答で対応する例が1つ見つかります。$ .postと$ .getは$ .ajaxの短縮形です。これまでに学習した情報と同じものは繰り返したくありません。したがって、$。ajaxを使用するだけで、グローバル設定を変更することなく、そのパラメーターの完全なセットを使用できます。

ちなみに、標準の$ .postを上書きすることはお勧めしません。それは私の個人的な意見ですが、私にとって重要なのは、プログラムが機能することだけでなく、プログラムを読んだすべての人が同じように理解することです。非常に重要な理由なしに標準メソッド上書きする、プログラムコードの読み取り誤解が生じる可能があります。だけではなく、元の$アヤックスフォームのjQueryを使用します。私のお勧め1つのより多くの時間を繰り返して私はそうjQuery.getjQuery.post、あなたは完璧に仕事だけでなく、プログラムを受けるが、誤解のない人で読み取ることができます。


1
優れた

8

post()への最後のパラメーターとして渡すことができる「json」データ型は、関数がサーバーの応答で予期するデータのタイプを示し、要求で送信するタイプを示しません。具体的には、「Accept」ヘッダーを設定します。

正直なところ、最善の策はajax()呼び出しに切り替えることです。post()関数は、利便性を目的としています。単純なフォーム投稿を行っているときのためのajax()呼び出しの簡略化バージョン。あなたは違います。

本当に切り替えたくない場合は、xpost()などの独自の関数を作成し、コンテンツタイプを設定して、指定されたパラメーターをjQuery ajax()呼び出しのパラメーターに変換するだけです。そうすれば、それらすべてのpost()関数をajax()関数に書き換えるのではなく、それらすべてをpostからxpost(またはその他)に変更するだけで済みます。


変更が必要なasp.net mvcコントローラーメソッドを呼び出す$ .post()メソッドのみ。純粋なjqueryのものは変更しないでください(autocomplete、diaplog、jqgridなど)。関連する$ .post()sに簡単な変更を加えることを望んでいました。しかし、それらを$ .ajax()に変換する必要があるようです。その大規模で非常にajaxの重いアプリなので、変更する必要のあるアプリはたくさんあります。
JK。

6

$ .postJSON()に対するこの単純なjquery API 拡張(https://benjamin-schweizer.de/jquerypostjson.htmlから)は、トリックを行います。他のすべてのネイティブjquery Ajax呼び出しと同様に、postJSON()を使用できます。イベントハンドラなどをアタッチできます。

$.postJSON = function(url, data, callback) {
  return jQuery.ajax({
    'type': 'POST',
    'url': url,
    'contentType': 'application/json; charset=utf-8',
    'data': JSON.stringify(data),
    'dataType': 'json',
    'success': callback
  });
};

他のAjax API(AngularJSの$ httpなど)と同様に、正しいcontentTypeをapplication / jsonに設定します。ここでは文字列化されるため、jsonデータ(JavaScriptオブジェクト)を直接渡すことができます。返されると予想されるdataTypeはJSONに設定されています。jQueryのpromiseのデフォルトイベントハンドラーをアタッチできます。次に例を示します。

$.postJSON(apiURL, jsonData)
 .fail(function(res) {
   console.error(res.responseText);
 })
 .always(function() {
   console.log("FINISHED ajax post, hide the loading throbber");
 });

5

私はこれが遅い答えであることを知っています、私は実際にMSベースのサービスへの投稿/ MSベースのサービスからの読み込みに使用するショートカット方法を持っています。それはMVCやASMXなどで動作します...

使用する:

$.msajax(
  '/services/someservice.asmx/SomeMethod'
  ,{}  /*empty object for nothing, or object to send as Application/JSON */
  ,function(data,jqXHR) {
    //use the data from the response.
  }
  ,function(err,jqXHR) {
    //additional error handling.
  }
);
//sends a json request to an ASMX or WCF service configured to reply to JSON requests.
(function ($) {
  var tries = 0; //IE9 seems to error out the first ajax call sometimes... will retry up to 5 times

  $.msajax = function (url, data, onSuccess, onError) {
    return $.ajax({
      'type': "POST"
      , 'url': url
      , 'contentType': "application/json"
      , 'dataType': "json"
      , 'data': typeof data == "string" ? data : JSON.stringify(data || {})
      ,beforeSend: function(jqXHR) {
        jqXHR.setRequestHeader("X-MicrosoftAjax","Delta=true");
      }
      , 'complete': function(jqXHR, textStatus) {
        handleResponse(jqXHR, textStatus, onSuccess, onError, function(){
          setTimeout(function(){
            $.msajax(url, data, onSuccess, onError);
          }, 100 * tries); //try again
        });
      }
    });
  }

  $.msajax.defaultErrorMessage = "Error retreiving data.";


  function logError(err, errorHandler, jqXHR) {
    tries = 0; //reset counter - handling error response

    //normalize error message
    if (typeof err == "string") err = { 'Message': err };

    if (console && console.debug && console.dir) {
      console.debug("ERROR processing jQuery.msajax request.");
      console.dir({ 'details': { 'error': err, 'jqXHR':jqXHR } });
    }

    try {
      errorHandler(err, jqXHR);
    } catch (e) {}
    return;
  }


  function handleResponse(jqXHR, textStatus, onSuccess, onError, onRetry) {
    var ret = null;
    var reterr = null;
    try {
      //error from jqXHR
      if (textStatus == "error") {
        var errmsg = $.msajax.defaultErrorMessage || "Error retreiving data.";

        //check for error response from the server
        if (jqXHR.status >= 300 && jqXHR.status < 600) {
          return logError( jqXHR.statusText || msg, onError, jqXHR);
        }

        if (tries++ < 5) return onRetry();

        return logError( msg, onError, jqXHR);
      }

      //not an error response, reset try counter
      tries = 0;

      //check for a redirect from server (usually authentication token expiration).
      if (jqXHR.responseText.indexOf("|pageRedirect||") > 0) {
        location.href = decodeURIComponent(jqXHR.responseText.split("|pageRedirect||")[1].split("|")[0]).split('?')[0];
        return;
      }

      //parse response using ajax enabled parser (if available)
      ret = ((JSON && JSON.parseAjax) || $.parseJSON)(jqXHR.responseText);

      //invalid response
      if (!ret) throw jqXHR.responseText;  

      // d property wrap as of .Net 3.5
      if (ret.d) ret = ret.d;

      //has an error
      reterr = (ret && (ret.error || ret.Error)) || null; //specifically returned an "error"

      if (ret && ret.ExceptionType) { //Microsoft Webservice Exception Response
        reterr = ret
      }

    } catch (err) {
      reterr = {
        'Message': $.msajax.defaultErrorMessage || "Error retreiving data."
        ,'debug': err
      }
    }

    //perform final logic outside try/catch, was catching error in onSuccess/onError callbacks
    if (reterr) {
      logError(reterr, onError, jqXHR);
      return;
    }

    onSuccess(ret, jqXHR);
  }

} (jQuery));

注:json.orgのJSファイルから変更されたJSON.parseAjaxメソッドもあり、MS "/Date(...)/"日付の処理を追加しています...

変更されたjson2.jsファイルは含まれていません。IE8の場合は、スクリプトベースのパーサーを使用します。これは、配列やオブジェクトのプロトタイプを拡張すると、ネイティブパーサーが壊れる場合があるためです。

このコードを改造してpromisesインターフェースを実装することを検討してきましたが、私にとっては非常にうまくいきました。


4

問題の核心は、執筆時点のJQueryには、getJSONが存在し、正しいことを実行している間、postJSONメソッドがないことです。

postJSONメソッドは次のことを行います。

postJSON = function(url,data){
    return $.ajax({url:url,data:JSON.stringify(data),type:'POST', contentType:'application/json'});
};

次のように使用できます:

postJSON( 'path/to/server', my_JS_Object_or_Array )
    .done(function (data) {
        //do something useful with server returned data
        console.log(data);
    })
    .fail(function (response, status) {
        //handle error response
    })
    .always(function(){  
      //do something useful in either case
      //like remove the spinner
    });

1

ドキュメントは 3.0のように、$ .postあなたは$アヤックスオプションを使用できることを意味し、設定オブジェクトを受け入れることを示している現在。3.0はまだリリースされておらず、コミット時にドキュメントへの参照の非表示について話しているが、将来的には探す必要がある!


1

次のJavaScriptコードでも同様の問題が発生しました。

var url = 'http://my-host-name.com/api/Rating';

var rating = { 
  value: 5,
  maxValue: 10
};

$.post(url, JSON.stringify(rating), showSavedNotification);

フィドラーのどこで私はリクエストを見ることができましたか:

  • ヘッダ: Content-Type: application/x-www-form-urlencoded; charset=UTF-8
  • 体: {"value":"5","maxValue":"5"}

その結果、私のサーバーはオブジェクトをサーバー側の型にマップできませんでした。

最後の行をこの行に変更した後:

$.post(url, rating, showSavedNotification);

フィドラーで私はまだ見ることができました:

  • ヘッダ: Content-Type: application/x-www-form-urlencoded; charset=UTF-8
  • 体: value=5&maxValue=10

しかし、サーバーは私が期待したものを返し始めました。


0

あなた自身のアダプター/ラッパーはどうですか?

//adapter.js
var adapter = (function() {

return {

    post: function (url, params) {
        adapter.ajax(url, "post", params);
        },
    get: function (url, params) {
        adapter.ajax(url, "get", params);
    },
    put: function (url, params) {
        adapter.ajax(url, "put", params);
    },
    delete: function (url, params) {
        adapter.ajax(url, "delete", params);
    },
    ajax: function (url, type, params) {
        var ajaxOptions = {
            type: type.toUpperCase(),
            url: url,
            success: function (data, status) {
                var msgType = "";
                // checkStatus here if you haven't include data.success = true in your
                // response object
                if ((params.checkStatus && status) || 
                   (data.success && data.success == true)) {
                            msgType = "success";
                            params.onSuccess && params.onSuccess(data);
                    } else {
                            msgType = "danger";
                            params.onError && params.onError(data);
                    }
            },
            error: function (xhr) {
                    params.onXHRError && params.onXHRError();
                    //api.showNotificationWindow(xhr.statusText, "danger");
            }
        };
        if (params.data) ajaxOptions.data = params.data;
        if (api.isJSON(params.data)) {
            ajaxOptions.contentType = "application/json; charset=utf-8";
            ajaxOptions.dataType = "json";
        }
        $.ajax($.extend(ajaxOptions, params.options));
    }
})();

    //api.js
var api = {
  return {
    isJSON: function (json) {
        try {
            var o = JSON.parse(json);
            if (o && typeof o === "object" && o !== null) return true;
        } catch (e) {}
        return false;
    }
  }
})();

そして非常にシンプルな使い方:

adapter.post("where/to/go", {
    data: JSON.stringify(params),
    onSuccess: function (data) {
        //on success response...
    }
    //, onError: function(data) {  //on error response... }
    //, onXHRError: function(xhr) {  //on XHR error response... }
});

試したが、期待した結果が得られない。Spring Boot Rest APIがあります。
Suraj Shingade

0

何らかの理由で、@ Adrienが提案したようにajaxリクエストでコンテンツタイプを設定しても、私の場合は機能しませんでした。ただし、実際に前にこれを行うと、$。postを使用してコンテンツタイプを変更できます。

$.ajaxSetup({
    'beforeSend' : function(xhr) {
        xhr.overrideMimeType('application/json; charset=utf-8');
    },
});

次に$.post電話をかけます。

$.post(url, data, function(), "json")

私はjQuery + IISに問題があり、これはjQueryがajaxリクエストにwindows-1252エンコーディングを使用することを理解するのに役立つ唯一のソリューションでした。


0

$ .postでこのようにContent-typeを変更できます

$ .post(url、data、function(data、status、xhr){xhr.setRequestHeader( "Content-type"、 "application / x-www-form-urlencoded; charset = utf-8");});


-1

CORS(Cross Origin Resource Sharing)の問題がある場合、$。postは機能しません。$ .Ajaxを次の形式で使用してみてください: "$ .ajax({url:someurl、contentType: 'application / json'、data:requestInJSONFormat、 headers:{'Access-Control-Allow-Origin': '*'}、 dataType: 'json'、type: 'POST'、async:false、success:function(Data){...}}); "


-19

application/json直接送信することはできません。GET/ POSTリクエストのパラメータである必要があります。

だからのようなもの

$.post(url, {json: "...json..."}, function());

この答えは正しくない可能性がありますが、低品質ではなく、質問に答えようとする試みです。口コミから
Wai Ha Lee
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.