Dav*_*Eyk 4 javascript bookmarklet xmlhttprequest
我正在尝试为http://esv.to建立的特殊URL缩短服务构建一个javascript bookmarklet,用于缩短经文引用(即"Matthew 5"变为" http://esv.to/Mt5 ".小书签应该对http://api.esv.to/Matthew+5做一个GET请求,返回text/plain响应http://esv.to/Mt5.
bookmarklet本身的代码如下所示(为了便于阅读而扩展):
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);
Run Code Online (Sandbox Code Playgroud)
代码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();
})();
Run Code Online (Sandbox Code Playgroud)
从http://esv.to本身调用时,书签正常工作.但是当在另一个页面上使用时,它不会.奇怪的是,当我看到来自Firebug的请求时,响应是200 OK,浏览器下载17个字节(返回字符串的长度),但响应体是空的!不会抛出任何错误,只是XmlHttpRequest对象上的空responseText.
现在,根据Bookmarklet的Ajax调用,GET不应该违反相同的原始政策.这是一个错误吗?有解决方法吗?
跨站点XMLHttpRequests只能在实现W3C 跨源资源共享规范的浏览器中完成,并且如果服务器返回相应的访问控制头(请参阅MDC文章),例如:
Access-Control-Allow-Origin: *
但并非所有浏览器都实现了这一点.进行跨站点请求的唯一可靠方法是使用JSONP,用于(未经测试)示例:
(function() {
function shorten(ref, callback){
var callbackFuncName = 'esvapiJSONPCallback' + (new Date()).valueOf();
var script = document.createElement('script');
script.type = "text/javascript";
script.src = "http://esv.to/api/" + escape(ref) + "?callback=" + callbackFuncName;
window[callbackFuncName] = function(shorturl){
script.parentNode.removeChild(script);
window.callbackFuncName = null;
delete window[callbackFuncName];
callback(shorturl);
};
document.getElementsByTagName("head")[0].appendChild(script);
}
var ref = prompt("Enter a scripture reference or keyword search to link to:", "");
shorten(ref, function(shorturl) {
prompt("Here is your shortened ESV URL:", shorturl);
});
})();
Run Code Online (Sandbox Code Playgroud)
当服务器看到callback参数时,它将需要返回text/javascript而不是text/plain,并且响应体将需要包含在所提供的回调的调用中,例如:
<?php
#... after $shorturl is set ...
if(isset($_GET['callback'])){
header('Content-Type: text/javascript');
$callback = preg_replace('/\W+/', '', $_GET['callback']); #sanitize
print $callback . "(" . json_encode($shorturl) . ");";
}
else {
header("Content-Type: text/plain");
print $shorturl;
}
?>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2324 次 |
| 最近记录: |