3

我正在开发一个项目,其中客户端在 ServerA 中有后端代码,而我的前端代码(应该通过 AJAX 请求与后端通信)位于 ServerB 上,它们位于不同的域中。由于相同的来源策略,我无法成功发出这些请求(POST 和 GET 都没有)。是否可以在不更改后端代码来处理 JSONP 的情况下以某种方式启用它?例如,将特定域列入白名单,还是什么?

我试图在我的本地网络中模拟这个,后端代码在 10.0.1.4(不同的机器)上运行,我从 localhost(apache)访问它,但无法找出任何不需要的东西使用 jsonp。进行调用时,我什至在后端的日志中都看不到任何内容,但它可以从 REST 客户端正常工作,只需加载 GET 请求的 URL。如何实现不使用 JSONP 的公共 API 请求?

我至少需要一种方法(POST 或 GET)才能工作。谢谢。

4

3 回答 3

4

是否可以在不更改后端代码来处理 JSONP 的情况下以某种方式启用它?例如,将特定域列入白名单,还是什么?

是的,您可以在您的域上编写一个服务器端脚本,作为您和远程域之间的桥梁,然后向您的脚本发送 AJAX 请求。

不要期待奇迹。如果您无法控制远程域,您将被淘汰。出于安全原因,内置在浏览器中的相同来源策略限制会破坏您。好吧,您总是可以编写自己的浏览器,但不执行此策略,但我想您明白我的意思。

常见的解决方法包括JSONPCORS,但它们涉及对远程域的控制。如果您无法控制,请阅读我的上一句以及我的第一句。

这是一个很好的指南,我邀请您咨询,其中涵盖了一些允许使用 jQuery 实现跨域 AJAX 的常用技术。然后调整最适合您的场景的那个。并且总是存在涉及使用服务器端脚本桥接两个域的重型火炮解决方案,如果其他解决方法都没有帮助您,则该脚本在 100% 的情况下可以防弹。

于 2012-07-09T22:16:53.463 回答
1

是否可以在不更改后端代码来处理 JSONP 的情况下以某种方式启用它?例如,将特定域列入白名单,还是什么?

嗯,基本上没有。您必须通过CORS允许 JSONP 或“白名单”事物(这很容易做到)。或者您可以使用 YQL 作为跨域代理

于 2012-07-09T22:19:10.090 回答
0

这里发布了三个解决方案:

http://devlog.info/2010/03/10/cross-domain-ajax/

我尝试了第三个选项,因为它对我有用..而且我不必承受任何额外的压力,因为它就像处理常规 ajax 调用一样处理事情。

更新答案,因为这是 2 年前发布的:

上面的链接不再有效。

服务器端代理:

旧页面还谈到了使用服务器端代理,这意味着您的服务器调用另一台服务器,获取所有数据并将其发送到基于该服务器的页面。一台服务器从另一台服务器获取数据没有问题。因此,您的页面可以对该服务器进行常规 ajax 调用。我没有选择这个选项,因为它需要更多的体力劳动。所以我建议使用此处详述的选项:

带有 jQ​​uery 的 JSONP

  1. 确保提供程序支持 JSONP。
  2. 将 dataType 选项设置为 jsonp,如果提供者使用除“回调”之外的其他 GET 参数,请为该参数名称指定 jsonp 选项。

$.ajax({ // ... Use the AJAX utility as you normally would dataType: 'jsonp', // ... });

jQuery 将为这个请求生成一个唯一的回调名称(类似于 json1268267816)。因此,来自 Web 服务的回复将类似于:

json1268267816({'uid': 23, 'username': 'Chroder', 'name': 'Christopher Nadeau'});

但是 jQuery 可以无缝地处理这一切,因此您作为开发人员只需使用相同的 jQuery 成功/失败/完成回调钩子像普通的 AJAX 请求一样处理它。

缺点:

此方法的第一个限制是您必须依赖提供者来实现 JSONP。提供者需要实际支持 JSONP——他们需要用回调函数名称包装他们的 JSON 数据。

然后下一个限制——这是一个很大的限制——是 JSONP 不支持 POST 请求。由于所有数据都作为 GET 数据在查询字符串中传递,因此如果您的服务需要传递长数据(例如,论坛帖子或评论或文章),您将受到严重限制。但对于大多数获取的数据多于推送的数据的消费者服务来说,这并不是什么大问题。

然而,

使用像 jQuery 这样支持 JSONP 的库,插入特殊脚本标签和创建特殊回调函数的这些细节都是自动处理的。使用 JS 库,JSONP 和真正的 AJAX 之间的唯一区别通常是您启用了“jsonp”选项。

于 2012-07-09T22:31:14.287 回答