我有一个名为urlExists的函数,我在几个项目中使用没有问题。现在我在患者面板中,需要在调用函数addEventListener之前检查是否存在js文件:
function urlExists(url){
var http = new XMLHttpRequest();
http.open('HEAD', url, false);
http.onreadystatechange = function(){
if(request.readyState==4){
return true;
}else{
return false;
}
}
}
//other part of code
if (urlExists('../../medvoice/speaker.js')){
beep.addEventListener('ended', function() {
var parameters = {
target: dados,
tts: {
name: 'lianetts'
},
binder: 'speak',
path: {
name: '../../medvoice/mediapool/',
link: '/medhosphsl/medvoice/mediapool/'
}
};
var speaker = new Speaker(parameters);
});
}
当一个put控制台登录urlExists时,控制台会显示测试短语,但是在onreadystatechange里面没有。我错过了什么?
答案 0 :(得分:2)
有几个问题:
您的return true
和return false
未从urlExists
返回,他们正在从onreadystatechange
回调中返回。 urlExists
在任何地方都没有明确return
,因此调用它始终会生成undefined
。
您永远不会致电send
来解除请求。
您正在使用readyState
来确定资源是否存在,但这只是告诉您请求的状态;你应该检查status
。
如果必须使用同步请求,则根本不需要或不需要onreadystatechange
处理程序。这是一个涉及所有这些问题的版本:
function urlExists(url){
var http = new XMLHttpRequest();
http.open('HEAD', url, false);
http.send();
return http.status === 200;
}
为了完整性:同步ajax请求会导致用户体验不佳,并且很可能在某些时候完全被淘汰。相反,使用异步请求并让urlExists
返回一个承诺:
function urlExists(url){
return new Promise(function(resolve) {
var http = new XMLHttpRequest();
http.open('HEAD', url);
http.onreadystatechange = function() {
if (http.readyState === 4) {
resolve(http.status === 200);
}
};
http.send();
});
}
// Usage:
urlExists("some-url").then(function(exists) {
console.log("Exists? " + exists);
});
使用fetch
和ES2015 +箭头功能的更现代的方式:
function urlExists(url) {
return fetch(url, {method: "HEAD"}).then(response => response.ok);
}
// Usage:
urlExists("some-url").then(exists => console.log("Exists? " + exists));
或者我们可以接受ES2017(下个月出局!):
async function urlExists(url) {
return (await fetch(url, {method: "HEAD"})).ok;
}
// Usage (in another async function):
console.log("Exists? " + await urlExists("some-url"));
附注:urlExists
仅适用于您可以通过ajax访问的网址,因此通常只适用于同一来源的网址。如果这是你的用例,那很好,但我想我会提到它。