Video标签添加跨域头信息后的缓存问题

问题复现

  1. 第一步的页面,这个页面有两个 video标签,他们的 src一样
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>testtitle>
head>
<body>
    <div class="container">
       <video controls width="400"  height="300" src="http://localhost:3000/video.mp4" alt="" >video>
    div>
body>
html>
  1. 为第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>testtitle>
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协议。

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%来作为缓存事件,而且每个浏览器厂家的实现也不一样。

规避这个问题

  1. 如果一开始就添加了 crossorigin=“anonymous”,那么理论上不会遇到当前这个问题。
  2. 如果一开始在没有添加 crossorigin="anonymous"的时候,添加了 Cache-Control或 没last-modified头,也不会遇到这样的问题
  3. 如果一旦报错,浏览器则不会发送任何http请求去纠正这个问题,js 也没办法控制浏览器去清理前端的缓存。

解决办法

  1. 已经出现问题的情况下,最有效的办法是请客户手动的强制刷新,清理缓存。
  2. 前端代码对报错的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...');
});

你可能感兴趣的:(缓存)