如何使用 jQuery 创建一个指定 contentType 的 jsonp POST 请求?

Posted

技术标签:

【中文标题】如何使用 jQuery 创建一个指定 contentType 的 jsonp POST 请求?【英文标题】:How to make a jsonp POST request that specifies contentType with jQuery? 【发布时间】:2011-04-21 01:56:14 【问题描述】:

我需要创建一个内容类型为“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 在您的域中吗?它返回什么格式? 【参考方案1】:

无法发出 JSONP POST 请求。

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

【讨论】:

如果我省略了 contentType,则会发出请求,服务器将其作为 POST 获取。 是的,jQuery 回退到 XMLHttpRequest,因为您不能通过 <script> 包含 POST。但这意味着 JSONP 响应永远不会起作用;如果它来自不同的主机名,由于同源策略,您将无法从响应中读取任何内容。 <script> 包含只能触发GET,任何你想发送给它的数据都必须放在 URL 查询参数中。 如果您指定 dataType: "jsonp" 并键入 "POST",则 "jsonp" 优先并作为 "GET" 请求发送("POST" 被忽略)。好处是这保留了 jsonp 功能,缺点是它默默地无法 POST 和 GETs 代替(所以你必须真正注意捕捉它......)【参考方案2】:

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" );

【讨论】:

这是否涉及安全问题?【参考方案3】:

有一个(黑客)解决方案我已经做过很多次了,你将能够使用 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');

这样做,您正在向任何发布请求打开服务器,您应该通过提供 ident 或其他内容来重新保护它。

通过这个方法,你也可以将请求类型从jsonp更改为json,两者都可以,只需设置正确的响应内容类型

jsonp

response.setContentType( "text/javascript; charset=utf-8" );

json

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

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

【讨论】:

我认为您所说的实际上是在使用 CORS。通过设置这些标头,您将触发客户端发起 CORS 请求。我不一定将其描述为“黑客”;这就是它应该做的方式。此外,我不建议使用“*”,而是回显客户端的来源并在服务器上进行白名单检查。更多详情请看这里:enable-cors.org/server.html

以上是关于如何使用 jQuery 创建一个指定 contentType 的 jsonp POST 请求?的主要内容,如果未能解决你的问题,请参考以下文章

如何让jquery动画效果在屏幕滚动到指定位置才执行

jquery如何让上一个页面打开指定页面

如何使用 css 转换重新创建我的 jQuery .animate() 元素缩放/平移?

教你怎么用jquery制作音乐播放器

jquery onclick 函数未定义

如何使用 jQuery 从 KTDatatable 获取行数据