如何使用jQuery进行指定contentType的jsonp POST请求?

41

我需要用内容类型为'application/json'的jsonp POST请求。我可以通过以下方式将POST请求发送到服务器:

      jQuery.ajax({
        type: 'POST',
        url: url,
        data: data,
        success: success,
        error: error,
        async: true,
        complete: complete,
        timeout: TIMEOUT,
        scriptCharset: 'UTF-8',
        dataType: 'jsonp',
        jsonp: '_jsonp',
      });

但是,当我添加以下行:contentType: "application/json"时,它开始将其作为OPTIONS请求发送,而不是POST请求。

我如何指定内容类型并仍将请求提交为POST?


你的URL是否在你的域名中?它返回什么格式? - SLaks
3个回答

53

无法使用JSONP进行POST请求。

JSONP通过创建一个<script>标签来执行来自不同域的Javascript,因此无法使用<script>标签发送POST请求。


如果我省略contentType,请求将被发送并作为POST请求接收到服务器端。 - Marcus
7
是的,jQuery会回退到XMLHttpRequest,因为你不能通过<script>引入来进行POST。但这意味着JSONP响应永远不会起作用;如果它来自一个不同的主机名,由于同源策略,你将无法从响应中读取任何内容。<script>引入只能触发GET方法,你想要发送给它的任何数据必须放在URL查询参数中。 - bobince
2
如果您指定dataType: "jsonp"和type "POST",则"jsonp"优先,并作为"GET"请求发送("POST"被忽略)。好处是这样可以保留jsonp功能,缺点是它会静默失败并转而使用GET(因此您必须非常注意才能捕捉到它...)。 - cmcculloh

7

dataType 中使用 json 并像这样发送:

        $.ajax({
            url: "your url which return json",
            type: "POST",
            crossDomain: true,
            data: data,
            dataType: "json",
            success:function(result){
                alert(JSON.stringify(result));
            },
            error:function(xhr,status,error){
                alert(status);
            }
        });

请将以下代码添加到您的服务器端文件中:

如果是PHP

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Max-Age: 1000');

如果是 Java:

response.addHeader( "Access-Control-Allow-Origin", "*" ); 
response.addHeader( "Access-Control-Allow-Methods", "POST" ); 
response.addHeader( "Access-Control-Max-Age", "1000" );

这个有安全问题吗? - Miguel Stevens

1

我有一个(hack)解决方案,我已经多次使用过,你可以使用JsonP进行发布。 (如果您要发布的表单大于2000个字符,则可以使用GET)

客户端应用程序Javascript

$.ajax({
  type: "POST", // you request will be a post request
  data: postData, // javascript object with all my params
  url: COMAPIURL, // my backoffice comunication api url
  dataType: "jsonp", // datatype can be json or jsonp
  success: function(result){
    console.dir(result);
  }
});

JAVA:

response.addHeader( "Access-Control-Allow-Origin", "*" ); // open your api to any client 
response.addHeader( "Access-Control-Allow-Methods", "POST" ); // a allow post
response.addHeader( "Access-Control-Max-Age", "1000" ); // time from request to response before timeout

PHP:

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Max-Age: 1000');

这样做会将您的服务器开放给任何POST请求,您应该通过提供标识或其他方式重新确保安全性。
使用此方法,您还可以将请求类型从jsonp更改为json,两者都可以工作,只需设置正确的响应内容类型。
jsonp
response.setContentType( "text/javascript; charset=utf-8" );

JSON
response.setContentType( "application/json; charset=utf-8" );

请注意,您的服务器将不再遵守SOP(同源策略),但谁在乎呢?

3
我认为你所谈论的是使用CORS。通过设置这些头信息,您将触发客户端发起CORS请求。我不会将其描述为“黑客行为”,这是应该的方式。此外,我不建议使用 "*",而是回显客户端的来源并在服务器上进行白名单检查。请查看此处获取更多详细信息:http://enable-cors.org/server.html - occasl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接