【问题标题】:How to use type: "POST" in jsonp ajax call如何在 jsonp ajax 调用中使用类型:“POST”
【发布时间】: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",请建议我该如何实现。

谢谢

【问题讨论】:

    标签: jquery jsonp http-post


    【解决方案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" );
    

    【讨论】:

    • 另一个答案解释了这段代码背后的原因:stackoverflow.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 以外的选择吗?
    • 如果您和我一样想知道如何实现这一点,请在同一问题中寻找其他答案:stackoverflow.com/a/17722058/102960
    【解决方案4】:
    【解决方案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.title
    • from 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),请再试一次。谢谢
      猜你喜欢
      • 2013-08-03
      • 1970-01-01
      • 2014-01-25
      • 1970-01-01
      • 2014-11-05
      • 1970-01-01
      • 2013-10-29
      • 2012-01-11
      • 2017-05-13
      相关资源
      最近更新 更多