跨域和缓存
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>
在script
、link
、img
标签的src
加载链接,此链接访问服务器的请求,并且返回可执行代码。
CORS预请求
我们不能通过设置Access-Control-Allow-Origin
来解决所有的跨域问题。
CORS其他限制
- 默认允许的方法只有:
GET
、HEAD
、POST
- 默认允许的
Content-Type
:text/plain
、multipart/form-data
、application/x-www-form-urlencoded
- 默认允许的请求头:
Accept
、Accept-Language
、Content-Language
、multipart/form-data
、text/plain
添加'Access-Control-Allow-Headers': 'x-Test-Cors'
查看network
面板会发现比之前多了一个请求,它的Request Method
是OPTIONS
。通过OPTIONS
请求获得服务端的允许,然后再实际发送POST
请求。
缓存头Cache-Control
可缓存性,public
、private
、no-cache
到期,max-age='<second>'
、s-maxage='<second>'
代理服务器、max-stale='<second>'
浏览器,发起端
重新验证,must-revalidate
、proxy-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);
Cookie
和Session
通过Set-Cookie
设置,下次请求会自动带上,键值对,可以设置多个
cookie
属性
max-age
和expires
设置过期时间Secure
只在https
的时候发送HTTPOnly
无法通过document.cookie
访问
response.writeHead(200, {
'Content-Type': 'text/html',
'Set-Cookie': ['id=123;max-age=2', 'abc=456;HttpOnly']
});