【问题标题】:Post form data created by an ajax call to a remote url将 ajax 调用创建的表单数据发布到远程 url
【发布时间】:2011-03-07 23:29:39
【问题描述】:

我想执行一个两阶段的帖子。第一个是我自己的服务的 AJAX 帖子,它创建表单数据,例如“email=blah&dude=car”等。

在 AJAX 调用的回调中,我需要以普通帖子的形式将该数据重新发布到远程站点。

我在想这样的事情:

var formData = "some form data";
$.ajax({
    type: 'POST',
    url: '/myservice', 
    data: formData,
    success: function(data, status) {
             xmlhttp=new XMLHttpRequest(); 
                        xmlhttp.open("POST","http://remotepage.com",true); 
                        xmlhttp.send(data);
    },
    error: function(XMLHttpRequest, textStatus, errorThrown) {
        //display error message     },
    dataType: "text",
});

但是,由于 remotepage.com 上的 XSS 防护,httpRequest 将失败。如何轻松将处理后的表单数据重新发布到远程 URL?

【问题讨论】:

  • 你能在你的网络服务中从服务器端重新发布吗?

标签: javascript ajax http forms xss


【解决方案1】:

您意识到,由于 same origin policy restrictionshttp://remotepage.com (xmlhttp.open("POST","http://remotepage.com",true);) 发送 AJAX 请求将无法正常工作,除非您的网站托管在 http://remotepage.com 上。

因此,要实现这一点,您需要在您的域上设置一个服务器端脚本,该脚本将充当您的域和远程域之间的桥梁,然后您将向您的脚本发送 AJAX 请求。同样因为您使用的是 jquery,所以在成功回调中使用它似乎更自然:

var formData = "some form data";
$.ajax({
    type: 'POST',
    url: '/myservice', 
    data: formData,
    success: function(data, status) {
        $.post('/some_bridge_script', formData);
    },
    error: function(XMLHttpRequest, textStatus, errorThrown) {
        //display error message     },
    dataType: "text",
});

如果远程域支持JSONP,您可以直接向它发送请求,但仅限于GET请求。

【讨论】:

  • 很好地重述了他的问题。
  • 好的。如果我要构建一个虚拟表单,然后使用 .submit() 怎么办?
  • 你关于 JSONP 的建议是一个非常非 RESTful 的设计,不是吗?
  • 好的。如果我要构建一个虚拟表单,然后使用 .submit() 会怎样? IE。 var submitForm = document.createElement("FORM"); document.body.appendChild(submitForm); submitForm.method = "POST"; submitForm.submit();
  • @user648960,创建表单对您没有好处,因为 remotepage.com 仍然没有机会对您进行身份验证。
【解决方案2】:

您需要向 remotepage.com 发送一个后台 GET 请求,询问您要修改/创建的资源的表单。这将允许 remotepage 在您的 cookie 存储中设置真实性令牌。隐藏此表单,使用已成功发布到 myservice 的数据填充它,然后发布隐藏的表单。这样,remotepage.com 将有机会检查您是否受信任。

编辑:添加代码示例

以下是我所设想的一些示例代码:

var formData = "some form data";
$.post({
  url: '/myservice', 
  data: formData,
  success: postToRemote,
  dataType: "JSON",
  error: function(XMLHttpRequest, textStatus, errorThrown) {
    // display error message
  },
});

因此,myservice 应该返回一个包含您在下面评论中讨论的已处理数据的 json 对象,而不是返回文本。回调将从远程页面请求您想要的表单。加载完成后,将执行匿名函数()中的块,填充表单,然后提交。

function postToRemote(data, status) {
  $("#empty_container_for_form").load("http://remotepage.com/get_hidden_form", function() {
    $("#hidden_form input#attribute_1").val(data.attribute1);
    $("#hidden_form input#attribute_2").val(data.attribute2);
    $.post({
      url: "http://remotepage.com",
      data: $("#hiddenForm").serialize()
    });
  });
}

另外,请确保使用 css 隐藏表单:

#empty_container_for_form { display: none; }

【讨论】:

  • 我可以在我的页面中包含一个 HTML 表单,让用户可以将信息发布到 Paypal... 那么为什么我不能自动化那个发布过程呢?
  • @user648960,您提交给贝宝的表单中可能有一些身份验证令牌,对吧?您向他们请求的 api 密钥或类似的东西?
  • 感谢您迄今为止的帮助!有一个与表单一起发送的用户 ID。但是,我希望在将所有信息发布到贝宝网站之前,将所有信息构建在数据对象中的服务器上。那么我可以将该数据字符串放入表单元素并手动发布吗?我不想解析返回的数据并构建表单元素。
  • @user648960,您实际上是在尝试实施 paypal 还是类似的东西?
猜你喜欢
  • 2015-10-10
  • 1970-01-01
  • 1970-01-01
  • 2016-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-29
  • 1970-01-01
相关资源
最近更新 更多