如何在 jsonp ajax 调用中使用类型:“POST”

Posted

技术标签:

【中文标题】如何在 jsonp ajax 调用中使用类型:“POST”【英文标题】:How to use type: "POST" in jsonp ajax call 【发布时间】:2011-05-29 08:03:38 【问题描述】:

我正在使用 JQuery ajax jsonp。我有以下 JQuery 代码:

 $.ajax(  
        type:"GET",        
        url: "Login.aspx",  // Send the login info to this page
        data: str, 
        dataType: "jsonp", 
        timeout: 200000,
        jsonp:"skywardDetails",
        success: function(result)
         
             // Show 'Submit' Button
            $('#loginButton').show();

            // Hide Gif Spinning Rotator
            $('#ajaxloading').hide();  
          

    );  

上面的代码工作正常,我只想将请求发送为 "POST" 而不是 "GET",请建议我该如何实现。

谢谢

【问题讨论】:

【参考方案1】:

您不能使用 JSONP 进行 POST...这种方式根本行不通,它会创建一个 <script> 元素来获取数据...必须是一个 GET 请求。除了发布到您自己的域作为代理发布到另一个域之外,您无能为力...但是用户将无法直接执行此操作并看到响应。

【讨论】:

您能否建议,我如何限制加密传递的 URL,以便没有人可以看到,因为它是 POST。 @MKS - 如果不通过您自己的域代理它,您真的无法做到……GET 请求本质上是“开放的”,比 POST 更重要 谢谢@NICK,您能否建议使用“GET”而不是“POST”是否安全,使用“GET”有什么缺点..请建议 @T.J. - 好吧,如果您的有效负载在 POST 而不是 URL 中,那么使用 SSL 可以更加安全,这就是我的目标。 通过 SSL 的 GET 请求在传输过程中不如 POST 安全的概念是不正确的。 URL 信息(例如路径、查询字符串等)都作为 HTTP 请求的一部分进行了加密。您的查询字符串不能在数据包级别被“嗅探”。然而,正如this SO question的回答中所述,还有其他问题@【参考方案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" );

【讨论】:

另一个答案解释了这段代码背后的原因:***.com/a/4528304/102960 @PratikButani 很好的答案。 在允许任何 3rd 方站点通过这些响应标头设置向您站点的应用程序发起 AJAX 调用时,是否存在任何潜在的安全隐患(例如 CSRF)? 这对我使用 Chrome v.36.0.1985.125 时不起作用。我收到了错误标准 - 没有“Access-Control-Allow-Origin”标头,即使我在 PHP 中有此标头,并且可以在网络选项卡中检索到的文件的标头下看到它。使用“GET”时,完全相同的请求有效。我已经尝试了许多排列,所以如果你想使用这个答案,我会担心它可能不适用于所有浏览器。 请注意,jsonp 的部分目的是能够让浏览器发送cookies。此处的代码无法实现这一点。为此,您可能必须根据本文档打开凭据:developer.mozilla.org/en-US/docs/Web/HTTP/…【参考方案3】:

现代浏览器允许跨域 AJAX 查询,它被称为 Cross-Origin Resource Sharing(另请参阅 this document 以获得更简短和更实用的介绍),并且最新版本的 jQuery 开箱即用地支持它;不过,您需要一个相对较新的浏览器版本(FF3.5+、IE8+、Safari 4+、Chrome4+;不支持 Opera AFAIK)。

【讨论】:

只是吹毛求疵,JSONP 不是 AJAX。 实际上我会更进一步地说 JSONP 不是 XMLHttpRequest 但它是 AJAX。无论如何,AJAX 定义不正确,因为它不会严格涵盖获取 JSON 而不是 XML 或同步获取。因此,鉴于 AJAX 的使用范围比它已经定义的要广泛,再加上 JSONP 主要与异步 javascript 一起使用,我很高兴 AJAX 也涵盖了 JSNOP。 这里的重要一点似乎是设置Access-Control-Allow-Origin: * 或类似的HTTP 标头。 (您可以声明单个允许的来源) 但是您仍然 [通常] 仅限于对 JSONP 请求使用 GET,而不是 POST,对吧?也就是说,我错过了这个答案如何回答 OP 的问题。就是这样,如果你必须使用 POST(这可能是这里的“真正”问题),你还有 JSONP 以外的选择吗? 如果您和我一样想知道如何实现这一点,请在同一问题中寻找其他答案:***.com/a/17722058/102960【参考方案4】:

JsonP 仅适用于类型:GET,

更多信息 (PHP) http://www.fbloggs.com/2010/07/09/how-to-access-cross-domain-data-with-ajax-using-jsonp-jquery-and-php/

.NET:http://www.west-wind.com/weblog/posts/2007/Jul/04/JSONP-for-crosssite-Callbacks

【讨论】:

【参考方案5】:

如果您只想使用$.ajax() 将表单POST 到您自己的站点(例如,模拟AJAX 体验),那么您可以使用jQuery Form Plugin。但是,如果您需要向其他域或您自己的域但使用不同的协议(非安全的http: 页面发布到安全的https: 页面)进行表单 POST,那么您会遇到单独使用 jQuery 无法解决的跨域脚本限制 (more info)。在这种情况下,您需要拿出大炮:YQL。说白了,YQL 是一种 Web 抓取语言,具有类似 SQL 的语法,允许您将整个互联网作为一个大表进行查询。就目前而言,在我看来,如果您想使用客户端 JavaScript 进行跨域表单 POST,那么 YQL 是唯一 [简单] 的方法。

更具体地说,您需要使用 YQL 的 Open Data Table 包含一个 Execute 块来实现这一点。关于如何做到这一点的一个很好的总结,你可以阅读文章“Scraping html documents that require POST data with YQL”。幸运的是,YQL 大师 Christian Heilmann 已经创建了一个Open Data Table that handles POST data。您可以在YQL Console 上使用 Christian 的“htmlpost”表。以下是 YQL 语法的细分:

select * - 选择所有列,类似于 SQL,但在这种情况下,列是查询返回的 XML 元素或 JSON 对象。在抓取网页的上下文中,这些“列”通常对应于 HTML 元素,因此如果只想检索页面标题,则可以使用select head.titlefrom htmlpost - 查询什么表;在这种情况下,请使用“htmlpost”开放数据表(如果此表不适合您的需要,您可以使用自己的自定义表)。 url="..." - 表单的 action URI。 postdata="..." - 序列化的表单数据。 xpath="..." - 要包含在响应中的节点的 XPath。这充当过滤机制,因此如果您只想包含<p> 标签,那么您将使用xpath="//p";包括您将使用的所有内容xpath="//*"

单击“测试”以执行 YQL 查询。一旦您对结果感到满意,请务必 (1) 单击“JSON”将响应格式设置为 JSON,以及 (2) 取消选中“诊断”以通过删除无关的诊断信息来最小化 JSON 有效负载的大小。最重要的是页面底部的 URL —— 这是您将在 $.ajax() 语句中使用的 URL。

在这里,我将向您展示使用此示例表单通过 YQL 查询执行跨域表单 POST 的确切步骤:

<form id="form-post" action="https://www.example.com/add/member" method="post">
  <input type="text" name="firstname">
  <input type="text" name="lastname">
  <button type="button" onclick="doSubmit()">Add Member</button>
</form>

您的 JavaScript 将如下所示:

function doSubmit() 
  $.ajax(
    url: '//query.yahooapis.com/v1/public/yql?q=select%20*%20from%20htmlpost%20where%0Aurl%3D%22' +
         encodeURIComponent($('#form-post').attr('action')) + '%22%20%0Aand%20postdata%3D%22' +
         encodeURIComponent($('#form-post').serialize()) +
         '%22%20and%20xpath%3D%22%2F%2F*%22&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=',
    dataType: 'json', /* Optional - jQuery autodetects this by default */
    success: function(response) 
      console.log(response);
    
  );

url 字符串是从 YQL 控制台复制的查询 URL,除了表单的编码 action URI 和动态插入的序列化输入数据。

注意:通过互联网传递敏感信息时,请注意安全隐患。确保您提交敏感信息的页面是安全的 (https:) 和 using TLS 1.x instead of SSL 3.0。

【讨论】:

【参考方案6】:

这是我写的JSONP分享给大家:

发送请求的页面http://c64.tw/r20/eqDiv/fr64.html

请自行将下面的 srec 保存为 .html c64.tw/r20/eqDiv/src/fr64.txt 要响应的页面,请自行将下面的 srec 保存到 .jsp c64.tw/r20/eqDiv/src/doFr64.txt

或在您的页面中嵌入代码:

函数 callbackForJsonp(resp)

var elemDivResp = $("#idForDivResp");
elemDivResp.empty();

try 

    elemDivResp.html($("#idForF1").val() + " + " + $("#idForF2").val() + "<br/>");
    elemDivResp.append(" = " + resp.ans + "<br/>");
    elemDivResp.append(" = " + resp.ans2 + "<br/>");

 catch (e) 

    alert("callbackForJsonp=" + e);


$(document).ready(function()

var testUrl = "http://c64.tw/r20/eqDiv/doFr64.jsp?callback=?";

$(document.body).prepend("post to " + testUrl + "<br/><br/>");

$("#idForBtnToGo").click(function() 

    $.ajax(

        url : testUrl,
        type : "POST",

        data : 
            f1 : $("#idForF1").val(),
            f2 : $("#idForF2").val(),
            op : "add"
        ,

        dataType : "jsonp",
        crossDomain : true,
        //jsonpCallback : "callbackForJsonp",
        success : callbackForJsonp,

        //success : function(resp) 

        //console.log("Yes, you success");
        //callbackForJsonp(resp);

        //,

        error : function(XMLHttpRequest, status, err) 

            console.log(XMLHttpRequest.status + "\n" + err);
            //alert(XMLHttpRequest.status + "\n" + err);

        

    );

);

);

【讨论】:

我试过了,所有数据在服务器(php)上作为 $_GET 参数接收 好吧,我已经修复了url链接(c64.tw/r20/eqDiv/fr64.html),请再试一次。谢谢

以上是关于如何在 jsonp ajax 调用中使用类型:“POST”的主要内容,如果未能解决你的问题,请参考以下文章

使用 JSONP 时如何捕获 jQuery $.getJSON(或数据类型设置为“jsonp”的 $.ajax)错误?

实现简单的PHP接口,以及使用js/jquery ajax技术调用此接口

如何在 jQuery ajax 调用中将 JSON 响应解析为 JSONP?

为啥我的 Ajax 请求包含数据类型:“jsonp”错误? [复制]

带有 jsonp 内容类型的 jQuery.ajax 请求后的解析器错误

jquery ajax使用JSONP解决跨域问题