跨站 AJAX 请求

IT技术 javascript ajax security xss
2021-02-05 01:55:21

我需要从网站向另一个域中托管的 REST Web 服务发出 AJAX 请求。

尽管这在 Internet Explorer 中运行良好,但其他浏览器(例如 Mozilla 和 Google Chrome)施加了更严格的安全限制,禁止跨站点 AJAX 请求。

问题是我无法控制站点所在的域和 Web 服务器。这意味着我的 REST Web 服务必须在其他地方运行,而且我无法设置任何重定向机制。

这是进行异步调用的 JavaScript 代码:

var serviceUrl = "http://myservicedomain";
var payload = "<myRequest><content>Some content</content></myRequest>";
var request = new XMLHttpRequest();
request.open("POST", serviceUrl, true); // <-- This fails in Mozilla Firefox amongst other browsers
request.setRequestHeader("Content-type", "text/xml");
request.send(payload);

如何在 Internet Explorer 之外的其他浏览器中使用此功能?

6个回答

也许JSONP可以提供帮助。

注意您必须更改您的消息以使用 json 而不是 xml

编辑

flickr 和twitter等主要网站支持 jsonp 和回调等

这种方法有多受欢迎?这似乎有点实验性。
2021-03-15 01:55:21
尽管从托管在与 REST 服务相同的域上的 iframe 发布 AJAX 请求是一个可行的解决方案(只要 iframe 和页面之间不需要通信),我一般不太喜欢 iframe因为它们的兼容性问题。所以 JSONNP 可能是目前可用的最佳解决方案。
2021-03-16 01:55:21
@annakata 显然,但他提到他无法处理网络服务器等,因此使用代理是不可能的。我不是在这里评论他的情况,只是为他的问题/问题提供一个可能的解决方案。
2021-03-17 01:55:21
这可能有效,但 JSONP 承认有问题:)
2021-03-22 01:55:21
@redsquare:同意,他在角落里@enrico:相当实验,但它被使用了
2021-04-11 01:55:21

标记为答案的帖子是错误的:iframes 文档无法访问父级。同源策略是双向的。

事实是,不可能以任何方式使用 xmlhttprequest 来使用基于休息的 Web 服务。从不同的域(没有任何框架)加载数据的唯一方法是使用 JSONP。任何其他解决方案都需要位于您自己域上的服务器端代理,或位于远程域上的客户端代理以及某种跨站点通信(如easyXDM)以在文档之间进行通信。

easyXSS 更名为easyXDM,也有不少改进
2021-03-26 01:55:21
-1 因为这不是不准确的。可以使用“父”DOM 对象从带有 JavaScript 的 IFRAME 访问父页面。例如,这将从 IFRAME 中修改页面中的元素: parent.document.getElementById("someDiv").innerHTML = "some content";
2021-04-03 01:55:21
我当时误解了你的回答。您是对的,当两者托管在不同的域中时,iframe 无法访问父页面的内容,反之亦然。但是,在我的情况下,使用 iframe 效果很好,因为它不需要以任何方式访问父页面,但它只是将 AJAX 请求发布到托管在同一域上的服务。
2021-04-06 01:55:21
您需要编辑您的答案,因为 SO 不允许我更改太旧的投票
2021-04-09 01:55:21
问题是关于来自不同域的文档 - 因此相同的来源策略将受到影响。如果父域来自域 B,则域 A 中的 IFrame 无法访问其父级的 contentDocument。作为easyXSS跨站库的作者,我对这方面有一些了解。
2021-04-10 01:55:21

这在 IE 中有效的事实是 IE 的安全问题,而不是功能。

不幸的是,跨站点脚本是被禁止的,可接受的解决方法是通过您自己的域代理请求:您真的没有能力添加或修改服务器端代码吗?

此外,次要解决方法 - 涉及通过脚本标签获取数据 - 仅支持 GET 请求,您可能可以使用 SOAP 服务破解它,但不支持您描述的 RESTful 服务的 POST 请求。

我真的不确定是否存在 AJAX 解决方案,您可能会回到 <form> 解决方案。

我同意允许 XSS 是 IE 中的一个安全漏洞。不幸的是,我无法控制 Web 服务器,因为它是托管在第三方提供商上的博客。我也考虑过使用 HTML 表单,但这会导致一个完整的页面发布而不是一个很好的异步调用。
2021-03-29 01:55:21

不太清楚的解决方法(但有效)是使用 iframe 作为对另一个站点的请求的容器。问题是,父级无法访问 iframe 的内容,只能导航 iframe 的“src”属性。但是 iframe 内容可以访问父级的内容。

因此,如果 iframe 的内容知道,他们可以调用父页面中的一些 javascript 内容或直接访问父页面的 DOM。

编辑: 示例:

function ajaxWorkaroung() {
    var frm = gewtElementById("myIFrame")
    frm.src = "http://some_other_domain"
}
function ajaxCallback(parameter){
    // this function will be called from myIFrame's content
}
IFrames 比 ajax 慢,而且在较旧的 IE 中我记得每次 iframe.src 更新时都会播放“点击”声音:(
2021-03-15 01:55:21
在 javascript 中,无法访问父 javascript 数据或跨域函数。答案是不真实的。
2021-03-15 01:55:21
@nagtur:前段时间我成功地使用了这个场景:|。
2021-04-09 01:55:21

使您的服务域接受跨源资源共享 (CORS)。

典型场景:大多数符合 CORS 的浏览器会首先发送一个 OPTIONS 标头,服务器应向该标头返回有关接受哪些标头的信息。如果标头满足服务对所提供请求的要求(允许的方法为 GET 和 POST、Allowed-Origin * 等),则浏览器将使用适当的方法(GET、POST 等)重新发送请求。

现在的一切都与您使用 IE 时相同,或者更简单地说,如果您发布到同一个域。

Caviots:某些服务开发SDK(尤其是WCF)会尝试处理请求,在这种情况下,您需要对OPTIONS 方法进行预处理以响应请求并避免该方法在服务器上被调用两次。

简而言之,问题出在服务器端。

编辑IE 9 及以下的 CORS 存在一个问题,即它没有完全实现。幸运的是,您可以通过从服务器端代码调用服务并让它通过您的服务器返回来解决这个问题(例如 mypage.aspx?service=blah&method=blahblah&p0=firstParam=something)。从这里开始,您的服务器端代码应该实现请求/响应流模型。