我用动态脚本标签做了一堆json请求。是否有可能检测到请求中是否存在错误(例如503错误,404错误)并在检测到错误时运行某些操作?
答案 0 :(得分:11)
使用ajax代替。 AFAIK无法检测脚本标记是否加载,如果没有,为什么它没有加载。使用ajax你可以加载json,它会告诉你为什么它没有加载。
使用像jQuery这样的库变得非常简单:
$.ajax({
type: "GET",
url: "test.js",
dataType: "script",
error: function(xhr, error, exception){
alert(xhr.status); //Will alert 404 if the script does not exist
}
});
答案 1 :(得分:4)
AFAIK,无法访问从文档加载的某些外部资源的状态代码(例如脚本,样式或图像)。甚至检测错误(例如,通过onerror
事件处理程序)并不是跨浏览器广泛支持的。
如果您加载的内容属于SOP,请使用XHR,以便您访问响应标头。否则,您可以尝试查看最近介绍的X-domain XHR。
答案 2 :(得分:3)
我假设你希望这个跨域工作,这就是为什么你不能使用XHR?
尝试为每个请求创建两个脚本标记,第一个执行标准JSONP请求,第二个基本上是错误处理程序。
如果第一个脚本标记执行,则清除回调中的错误处理程序。但是,如果第一个获得404,则将运行第二个脚本标记内的错误处理程序。
您可能还想设置超时,以应对缓慢的JSONP响应。
答案 3 :(得分:1)
答案 4 :(得分:1)
如果您正在使用jQuery,请查看jQuery-JSONP这是一个jQuery插件,可以为您执行<script>
插入,并检测提取错误。
从项目页面引用jQuery-JSONP功能:
答案 5 :(得分:0)
如果要检测错误,请侦听error
事件,并将错误的fileName
属性与脚本的文件名进行比较。如果匹配,则处理错误。问题是,我认为fileName
属性是Firefox和Opera。大多数具有错误堆栈跟踪的浏览器也可以模拟此行为。
以下是EricBréchemier所要求的一个例子:
var getErrorScriptNode = (function () {
var getErrorSource = function (error) {
var loc, replacer = function (stack, matchedLoc) {
loc = matchedLoc;
};
if ("fileName" in error) {
loc = error.fileName;
} else if ("stacktrace" in error) { // Opera
error.stacktrace.replace(/Line \d+ of .+ script (.*)/gm, replacer);
} else if ("stack" in error) { // WebKit
error.stack.replace(/at (.*)/gm, replacer);
loc = loc.replace(/:\d+:\d+$/, "");
}
return loc;
},
anchor = document.createElement("a");
return function (error) {
anchor.href = getErrorSource(error);
var src = anchor.href,
scripts = document.getElementsByTagName("script");
anchor.removeAttribute("href");
for (var i = 0, l = scripts.length; i < l; i++) {
anchor.href = scripts.item(i).src;
if (anchor.href === src) {
anchor.removeAttribute("href");
return scripts.item(i);
}
}
};
}());
答案 6 :(得分:0)
如果您需要跨域(并且需要页面可移植),则必须使用动态脚本标记。
如果您有权访问远程服务器,则可以从服务器传回错误代码,并让服务器页面返回200.
无论您是否有访问权限,都可以在创建脚本标记时使用setTimeout,如果在调用jsonp处理程序之前它将过期,则会传递一个将触发错误的函数。如果已调用错误处理程序,请确保jsonp处理程序中止。
您需要通过全局集合跟踪每个请求,但您将获得取消和计算请求的功能。这类似于像jQuery这样的库管理XHR对象的方式。