3

我正在尝试实现这个http://wiki.kolmisoft.com/index.php/MOR_API_login。我已启用服务器中的设置以允许 API。Javascript 的问题是,我的主要网站在 domain website.com 下运行,而星号服务器在 voip.website.com 中运行。因此,当我尝试使用 jQuery 调用 url 时,我得到 XMLHttpRequest cannot load http://voip.website.com/.../.../ ..... Origin http://sites is not allowed by Access -控制-允许-来源。

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

4

2 回答 2

4

所有浏览器都执行包括整个主机(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 等等。

于 2012-04-30T20:31:10.017 回答
2

您将需要使用 JSONP 将数据包装在回调中并对其进行 mimetypetext/javascript以规避跨域策略。

使用 JSONP 与 .net 对话的 JQuery 有哪些好的示例?

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

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

编辑

由于您说您需要发送帖子,因此我将做更多详细说明我的第二种方法。就像概念证明一样,我将使用 PHP 来详细说明需要做什么,但是将这个一般想法移植到另一种脚本语言应该很简单。

假设我可以在您的域上制作一个包罗万象的脚本,www.yourdomain.com/data.php 该文件中的逻辑需要从 http 请求中读取我所有的帖子变量,将它们作为对新域的请求放入 curl 实例中,执行该请求,然后将请求的响应输出回我的 ajax XHR,这样就好像一开始就没有中介。

我喜欢使用jscol 的 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保护端点。这确实特定于您如何进行客户端/服务器端交互,并且有点超出了重定向器的范围......基本上只需确保您有一个服务器定义的哈希盐,并让摘要与您的发布请求一起发送,确保第三方不能简单地发布到您的中介终端。

编辑

万一有人从谷歌偶然发现,我用我自己的方法创建了一个库,可以在这里找到。

于 2012-04-30T20:32:50.880 回答