跨域和缓存

CORS跨域

搭建服务端:

server.js

const http = require('http');
const fs = require('fs');
http.createServer((request, response) => {
  console.log('request come', request.url);
  const html = fs.readFileSync('index.html', 'utf8');
  response.writeHead(200, {
    'Content-Type': 'text/html'
  });
  response.end(html);
}).listen(8888);
console.log('server listening on 8888');

server2.js

const http = require('http');
http.createServer(function (request, response) {
  console.log('request come', request.url);
  response.writeHead(200, {
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Headers': 'x-Test-Cors',
    'Access-Control-Allow-Methods': 'POST,PUT,Delete',
    'Access-Control-MAX-AGE': '1000'
  });
  response.end('123abc')
}).listen(8887);
console.log('server is listening on 8887');

AJAX请求

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1:8000');
xhr.send();

JSONP

<script src="http://127.0.0.1:8000"></script>

scriptlinkimg标签的src加载链接,此链接访问服务器的请求,并且返回可执行代码。

CORS预请求

我们不能通过设置Access-Control-Allow-Origin来解决所有的跨域问题。

CORS其他限制

添加'Access-Control-Allow-Headers': 'x-Test-Cors'查看network面板会发现比之前多了一个请求,它的Request MethodOPTIONS。通过OPTIONS请求获得服务端的允许,然后再实际发送POST请求。

缓存头Cache-Control

可缓存性publicprivateno-cache

到期max-age='<second>'s-maxage='<second>'代理服务器、max-stale='<second>'浏览器,发起端

重新验证must-revalidateproxy-revalidate

浏览器缓存

const http = require('http');
const fs = require('fs');
http.createServer((request, response) => {
  console.log('request come', request.url);

  if (request.url === '/') {
    const html = fs.readFileSync('index.html', 'utf8');
    response.writeHead(200, {
      'Content-Type': 'text/html'
    });
    response.end(html);
  }

  if (request.url === '/script.js') {
    response.writeHead(200, {
      'Content-Type': 'text/javascript',
      'Cache-Control': 'max-age=200,public'
    });
  }
  response.end('console.log("script loaded twice")')

}).listen(8888);
console.log('server listening on 8888');

资源验证

浏览器-创建请求->本地缓存—>代理缓存—>源服务器

验证头:

Last-Modified上次修改时间,配合If-Modified-Since或者If-Unmodified-Since使用

Etag数据签名,配合If-Modified或者If-Non-Match使用、对比资源的签名判断是否使用缓存

http.createServer((request, response) => {
  console.log('request come', request.url);

  if (request.url === '/') {
    const html = fs.readFileSync('index.html', 'utf8');
    response.writeHead(200, {
      'Content-Type': 'text/html'
    });
    response.end(html);
  }

  if (request.url === '/app.js') {
    const etag = request.headers['if-none-match'];
    if (etag === '777') {
      response.writeHead(304, {
        'Content-Type': 'text/javascript',
        'Cache-Control': 'max-age=20000000,no-cache',
        'Last-Modified': '123',
        'Etag': '777'
      });
      response.end('123')
    } else {
      response.writeHead(200, {
        'Content-Type': 'text/javascript',
        'Cache-Control': 'max-age=20000000,no-cache',
        'Last-Modified': '123',
        'Etag': '777'
      });
      response.end('console.log("script loaded twice")')
    }
  }
}).listen(8888);

通过Set-Cookie设置,下次请求会自动带上,键值对,可以设置多个

cookie属性

response.writeHead(200, {
  'Content-Type': 'text/html',
  'Set-Cookie': ['id=123;max-age=2', 'abc=456;HttpOnly']
});