从浏览器到另一台服务器的HTTP POST请求

时间:2012-04-30 20:25:59

标签: jquery ajax

我正在努力实现这个http://wiki.kolmisoft.com/index.php/MOR_API_login。我已启用服务器中的设置以允许API。 Javascript的问题是,我的主网站运行在域名website.com下,而星号服务器运行在voip.website.com。所以当我尝试使用jQuery调用url时,我得到XMLHttpRequest无法加载http://voip.website.com/.../.../ ...... Access-Control-Allow-Origin不允许原点http://sites

我不确定实现这一目标的最佳方法是什么。任何一点都会有很大的帮助。

2 个答案:

答案 0 :(得分:3)

所有浏览器都会强制执行包含整个主机的same-origin policy(website.com与voip.website.com)。除非主机是相同的,否则您无法处理从Ajax帖子返回的JSON。

有一种称为JSONP的解决方法。诀窍是你将回复包装在JavaScript函数中。您看,同源策略仅适用于数据,而不适用于完整的脚本本身。因此,如果响应是JavaScript而不是数据,则浏览器认为您需要运行此脚本。

例如,假设你的回答是这个JSON:

{
  firstName: 'Abed',
  lastName: 'Nadir',
  school: 'Greendale Community College'
}

相反,你回答:

({
  firstName: 'Abed',
  lastName: 'Nadir',
  school: 'Greendale Community College'
})

需要注意的是,前后括号使其成为JavaScript匿名函数而不是JSON数据。您所做的只是接收该响应并在之前和之后剥离JavaScript代码。

健全的声音?它是,但每个人都这样做,包括Flickr,谷歌,亚马逊,Facebook,等等。

答案 1 :(得分:2)

您需要使用JSONP将数据包装在回调中,并将其mimetype为text/javascript以规避跨域策略。

What are some good examples of JQuery using JSONP talking to .net?

标题提到.net,但服务器端环境与客户端实现无关。

一个可行的替代方法是在您自己的域上设置服务器端脚本,该脚本将使用CURL(或任何其他http lib)转发请求,然后将响应输出到脚本的XHR请求。此方法在您的客户端脚本和您尝试访问的远程域之间设置了一个捕获,因为curl或任何其他服务器端http lib不受跨域策略的约束。

修改

因为你说你需要发一个帖子,所以我会再详细说明我的第二种方法。正如概念验证一样,我将使用PHP来详细说明需要完成的工作,但将这个概念移植到另一种脚本语言应该很简单。

假设我可以在www.yourdomain.com/data.php域中为您的域创建一个catchall脚本。该文件中的逻辑需要从http请求中读取我的所有post vars,将它们作为对新请求的请求放入curl实例中域,执行该请求,然后将请求的响应输出回我的ajax XHR,这样就好像从来没有一个中间人。

我喜欢使用jscol's OOCurl来使curl的语法更漂亮一些。

<?
reqire_once('path/to/oocurl.php');
$c = new Curl('voip.otherdomain.com/api'); // instantiate with the url endpoint for the api
$c->post = True;
// Set the postfields for the child request to the same as the parent
$c->postfields = $_POST;
//Bust if there is an error and output that instead  
$c->failoneerror = True;
$response = $c->exec();
if($c->errno()){
  //there was an error, what was it?
  header('Status:' . $c->info(CURLINFO_HTTP_CODE));
  echo $c->error();
}else{
  //success, echo output
  header('Content-type: application/json');
  echo $response;
}
?>

将ajax请求发送到此类脚本将透明地将它们移交给CURL的构造函数中指定的其他域。请注意,我假设返回的mimetype是json - 您可能需要调整它以适合您的API。

如果您拥有api的身份验证凭据,则需要将其作为附加的post vars手动编码到请求中,并使用hmac保护端点。这实际上特定于您如何进行客户端/服务器端交互,并且稍微超出了重定向器的范围...基本上只需确保您有服务器定义的哈希盐并将摘要与您的发布请求一起发送,确保第三方不能简单地向您的中间人发帖。

修改

如果有人从Google绊倒,我自己创建了一个图书馆,我可以采用这种方法here.