使用JavaScript有没有一种方法可以判断服务器上的资源是否可用?例如,我已经将图像1.jpg-5.jpg加载到html页面中。我想每隔一分钟调用一个JavaScript函数,大致执行以下伪代码...
if "../imgs/6.jpg" exists:
var nImg = document.createElement("img6");
nImg.src = "../imgs/6.jpg";
你有什么想法?谢谢!
使用JavaScript有没有一种方法可以判断服务器上的资源是否可用?例如,我已经将图像1.jpg-5.jpg加载到html页面中。我想每隔一分钟调用一个JavaScript函数,大致执行以下伪代码...
if "../imgs/6.jpg" exists:
var nImg = document.createElement("img6");
nImg.src = "../imgs/6.jpg";
你有什么想法?谢谢!
您可以使用以下内容:
function imageExists(image_url){
var http = new XMLHttpRequest();
http.open('HEAD', image_url, false);
http.send();
return http.status != 404;
}
$.get(image_url)
.done(function() {
// Do something now you know the image exists.
}).fail(function() {
// Image doesn't exist - do something else.
})
您可以利用图像预加载器的基本工作方式来测试图像是否存在。
function checkImage(imageSrc, good, bad) {
var img = new Image();
img.onload = good;
img.onerror = bad;
img.src = imageSrc;
}
checkImage("foo.gif", function(){ console.log("good"); }, function(){ console.log("bad"); } );
checkImage("favicon.ico", function(){ console.log("good"); }, function(){ console.log("bad"); } );
{{链接1:JSFiddle}}
return
语句来完成这个操作。 - Sablefosteonload
和onerror
事件将告诉您图像是否成功加载或是否发生错误:
var image = new Image();
image.onload = function() {
// image exists and is loaded
document.body.appendChild(image);
}
image.onerror = function() {
// image did not load
var err = new Image();
err.src = '/favicon.ico';
document.body.appendChild(err);
}
image.src = "../imgs/6.jpg";
更好、现代的方法是使用ES6 Fetch API 来检查图片是否存在:
fetch('https://via.placeholder.com/150', { method: 'HEAD' })
.then(res => {
if (res.ok) {
console.log('Image exists.');
} else {
console.log('Image does not exist.');
}
}).catch(err => console.log('Error:', err));
请确保您正在进行相同源请求,或者服务器已启用CORS。
getInitialState: function(event) {
return {image: "http://example.com/primary_image.jpg"};
},
handleError: function(event) {
this.setState({image: "http://example.com/failover_image.jpg"});
},
render: function() {
return (
<img onError={this.handleError} src={src} />;
);
}
基本上就是@espascarello和@adeneo回答的一个经过承诺化的版本,带有一个回退参数:
const getImageOrFallback = (path, fallback) => {
return new Promise(resolve => {
const img = new Image();
img.src = path;
img.onload = () => resolve(path);
img.onerror = () => resolve(fallback);
});
};
// Usage:
const link = getImageOrFallback(
'https://www.fillmurray.com/640/360',
'https://via.placeholder.com/150'
).then(result => console.log(result) || result)
2021年3月更新:
在与@hitautodestruct的交谈后,我决定添加一个更具“规范性”的Promise
函数版本。现在拒绝了onerror
情况,但随后被捕获并返回默认值:
function getImageOrFallback(url, fallback) {
return new Promise((resolve, reject) => {
const img = new Image()
img.src = url
img.onload = () => resolve(url)
img.onerror = () => {
reject(`image not found for url ${url}`)
}
}).catch(() => {
return fallback
})
}
getImageOrFallback("https://google.com", "https://picsum.photos/400/300").then(validUrl => {
console.log(validUrl)
document.body.style.backgroundImage = `url(${validUrl})`
})
html, body {
height: 100%;
background-repeat: no-repeat;
background-position: 50% 50%;
overflow-y: hidden;
}
注意: 我个人可能更喜欢fetch
的解决方案,但它有一个缺点 - 如果您的服务器以特定方式配置,则即使文件不存在,它也可以返回200 / 304。另一方面,这种方法可以完成工作。
fetch
,您可以使用 response
对象的 ok
属性来检查请求是否成功:fetch(url).then(res => {if(res.ok){ /*存在*/} else {/*不存在*/}});
- attacomsianbackground-image: url('/a/broken/url')
在 Chrome 74 中会得到 200
和 ok
的返回。 - HynekSonerror
回调中拒绝 Promise,而不是解决它。new Promise( (resolve, reject) => { /*...*/ img.onerror = () => reject('Not found') } )
- hitautodestructPromise.all()
内使用此模式,其中拒绝一个项目将拒绝整个列表。而且,我期望它总是返回某些内容(即现有的图像URL:因此函数名称)。虽然我不是FP极客,但我喜欢将其视为一个Either
单子。 - HynekSPromise.all()
。
我认为,如果你的答案是“一个经过承诺的版本...”,那么它应该尽可能接近经典的承诺,否则可能会对不熟悉承诺的人造成困惑。此外,您可能要考虑使用 Promise.allSettled()
而不是 Promise.all()
,以便在任何 reject
上不会失败所有承诺。 - hitautodestructonerror
上拒绝,但然后捕获并返回默认值)。它应该也能在Promise.all
中正常工作。感谢David Walsh(https://davidwalsh.name/javascript-promise-catch)的贡献。 - HynekSfunction doesFileExist(urlToFile)
{
var xhr = new XMLHttpRequest();
xhr.open('HEAD', urlToFile, false);
xhr.send();
if (xhr.status == "404") {
console.log("File doesn't exist");
return false;
} else {
console.log("File exists");
return true;
}
}
这里提供了基于true
/false
返回值的Promise
函数版本:
new Image();
方法(推荐):async function imageExists(imgUrl) {
if (!imgUrl) {
return false;
}
return new Promise(res => {
const image = new Image();
image.onload = () => res(true);
image.onerror = () => res(false);
image.src = imgUrl;
});
}
// test
(async () => {
// true
console.log(await imageExists('https://www.gstatic.com/webp/gallery3/1.png'));
// false
console.log(await imageExists('https://www.gstatic.com/webp/gallery3/DOES_NOT_EXIST_THERE.png'));
})()
XMLHttpRequest
(数据较少,但可能会导致跨域问题):async function fileExists(fileUrl) {
if (!fileUrl) {
return false;
}
return new Promise(res => {
const http = new XMLHttpRequest();
http.open('HEAD', fileUrl, true);
http.send();
http.onload = () => {
res(http.status != 404);
};
http.onerror = () => {
res(false);
};
});
}
// test
(async () => {
// true
console.log(await fileExists('https://www.gstatic.com/webp/gallery3/1.png'));
// false
console.log(await fileExists('https://www.gstatic.com/webp/gallery3/DOES_NOT_EXIST_THERE.png'));
})()
fetch
(现代浏览器,数据更少,可能存在CORS问题)async function fileExists(fileUrl) {
if (!fileUrl) {
return false;
}
const res = await fetch(fileUrl, {
method: 'HEAD',
});
return !!res.ok;
}
// test
(async () => {
// false
console.log(await fileExists('https://www.gstatic.com/webp/gallery3/1.png'));
// false
console.log(await fileExists('https://www.gstatic.com/webp/gallery3/DOES_NOT_EXIST_THERE.png'));
})()
// with `new Image();` method
async function imageExists(imgUrl: string | null | undefined): Promise<boolean> {
if (!imgUrl) {
return false;
}
return new Promise(res => {
const image = new Image();
image.onload = () => res(true);
image.onerror = () => res(false);
image.src = imgUrl;
});
}
// with `XMLHttpRequest` method
async function fileExists(fileUrl: string | null | undefined): Promise<boolean> {
if (!fileUrl) {
return false;
}
return new Promise(res => {
const http = new XMLHttpRequest();
http.open('HEAD', fileUrl, false);
http.send();
http.onload = () => {
res(http.status != 404);
};
http.onerror = () => {
res(false);
};
});
}
// with `fetch` method
async function fileExists(fileUrl: string | null | undefined): Promise<boolean> {
if (!fileUrl) {
return false;
}
const res = await fetch(fileUrl, {
method: 'HEAD',
});
return !!res.ok;
}
我在使用JS显示用户图像时遇到了一些问题:如果用户图像丢失,它会报错。
事实证明,您可以在HTML中执行以下操作,以在加载图像失败时显示特定图像
<img src="img/path/image.png" onerror="javascript:this.src='img/path/no-image.png'">
只是想分享一下...也许这可以为你节省一些时间!
fileExists
会是更好的名字,因为这个函数并不检查图像是否存在于服务器上。它只检查文件是否可以从服务器访问。没有检查该文件是否实际上是一个图像。它可能是.pdf、.html、一些随机文件重命名为*.jpg或*.png。如果某事以 .jpg 结尾,这并不意味着它是100% 的图像 :) - CoR