小书签中的 XmlHttpRequest 在 GET 上返回空响应文本?
我正在尝试为我们在 http://esv.to 用于缩短经文引用(即“马太福音 5”变为“http://esv.to/Mt5”。小书签应该对 http://api.esv.to/Matthew+5< 执行 GET 请求/a>,它返回 http://esv.to/Mt5
的 text/plain
响应。
书签本身的代码如下所示(为了便于阅读而进行了扩展)。 :
var body = document.getElementsByTagName('body')[0], script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'http://esv.to/media/js/bookmarklet.js';
body.appendChild(script);
void(0);
来自 http://esv.to/media/js/bookmarklet.js
的代码如下所示:
(function() {
function shorten(ref, callback) {
var url = "http://esv.to/api/" + escape(ref);
var req = new XMLHttpRequest();
req.onreadystatechange = function shortenIt() {
if ( this.readyState == 4 && this.status == 200 ) {
callback(req.responseText);
};
};
req.open( "GET", url );
req.send();
};
function doBookmarklet() {
var ref = prompt("Enter a scripture reference or keyword search to link to:", "")
shorten(ref, function (short) {
prompt("Here is your shortened ESV URL:", short);
});
};
doBookmarklet();
})();
当从 http://esv.to 本身,书签可以正常工作。但是当在另一个页面上使用时,它不能。奇怪的是,当我查看来自 Firebug 的请求时,响应是 200 OK
,浏览器下载了17个字节(返回字符串的长度),但响应正文为空!不会引发任何错误,只是 XmlHttpRequest 对象上出现一个空的responseText。
现在,根据 来自 Bookmarklet 的 Ajax 调用,GET 不应违反同源策略。这是一个错误吗?有解决方法吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
跨站点 XMLHttpRequest 只能在实现 W3C 跨源资源共享 规范的浏览器中完成如果服务器返回适当的访问控制标头(请参阅 MDC 文章),例如:
Access-Control-Allow-Origin: *
但这并不是所有浏览器都实现的。执行跨站点请求的唯一可靠方法是使用 JSONP,对于 (未测试)示例:
当服务器看到
callback
参数时,它需要返回text/javascript
而不是text/plain
,并且响应body 需要包装在所提供回调的调用中,例如:Cross-site XMLHttpRequests can only be done in browsers that implement the W3C Cross-Origin Resource Sharing spec and if the server returns the appropriate access control headers (see MDC article), e.g.:
Access-Control-Allow-Origin: *
But this is not implemented by all browsers. The only sure-fire way to do cross-site requests is to use JSONP, for (untested) example:
When the server sees the
callback
parameter it would then need to returntext/javascript
instead oftext/plain
, and the response body would need to be wrapped in an invocation of the provided callback, for example: