问题复现
- 第一步的页面,这个页面有两个 video标签,他们的 src一样
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test</title>
</head>
<body>
<div class="container">
<video controls width="400" height="300" src="http://localhost:3000/video.mp4" alt="" ></video>
</div>
</body>
</html>
- 为第video标签添加参数 crossorigin=“anonymous” ,那么会报错。“xxxx” has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test</title>
</head>
<body>
<div class="container">
<video controls width="400" crossorigin="anonymous" height="300" src="http://localhost:3000/video.mp4" alt="" ></video>
</div>
</body>
</html>
问题分析
这里的video.mp4的静态文件服务器,服务端的代码用 express写的,后面会贴出,我们这里分析一下http协议。文章来源:https://www.toymoban.com/news/detail-564483.html
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, PUT, DELETE, HEAD
Access-Control-Max-Age: 7200
ETag: "14a75b-+3U9KJ4h8BvTNuddNn1RqzOBBfA"
Content-Type: video/mp4
Content-Length: 1353563
last-modified: Mon, 10 Jul 2023 04:05:15 GMT
Date: Mon, 10 Jul 2023 07:32:31 GMT
通过上面的response请求,我们可以看出,这里并没有使用Cache-Control 或expires来控制浏览器的缓存,那么缓存的重任就落到了last-modified的肩膀上,通过查资料,我们发现last-modified一般是根据与现在的时间差的 10%来作为缓存事件,而且每个浏览器厂家的实现也不一样。文章来源地址https://www.toymoban.com/news/detail-564483.html
规避这个问题
- 如果一开始就添加了 crossorigin=“anonymous”,那么理论上不会遇到当前这个问题。
- 如果一开始在没有添加 crossorigin="anonymous"的时候,添加了 Cache-Control或 没last-modified头,也不会遇到这样的问题
- 如果一旦报错,浏览器则不会发送任何http请求去纠正这个问题,js 也没办法控制浏览器去清理前端的缓存。
解决办法
- 已经出现问题的情况下,最有效的办法是请客户手动的强制刷新,清理缓存。
- 前端代码对报错的video检测资源状态,跳过这个资源的播放或做其他的操作。
服务端代码
const express = require('express');
const app = express();
const path = require('path');
const fs = require('fs');
const etag = require('etag');
// Custom CORS middleware
const cors = (req, res, next) => {
const origin = req.headers.origin;
if (origin) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, HEAD');
res.setHeader('Access-Control-Max-Age', '7200');
}
next();
};
app.use(cors); // Use cors middleware for all routes
app.use(express.static('public'));
app.get('/video.mp4', function(req, res) {
const filePath = path.join(__dirname, 'public', 'v.mp4');
const stat = fs.statSync(filePath);
fs.readFile(filePath, (err, data) => {
if (err) {
console.error(err);
res.status(500).send('Server Error');
} else {
res.setHeader('ETag', etag(data));
res.setHeader('Content-Type', 'video/mp4');
res.setHeader('Content-Length', stat.size);
res.setHeader('last-modified', stat.mtime.toUTCString());
//res.setHeader('Cache-Control', 'public, max-age=10');
res.removeHeader('Connection')
res.removeHeader('Keep-Alive')
res.end(data);
}
});
});
app.listen(3000, function() {
console.log('Listening on port 3000...');
});
到了这里,关于Video标签添加跨域头信息后的缓存问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!