A网页设置的 Cookie,B网页不能打开,除非这两个网页"同源"。所谓"同源"指的是"三个相同"。
是为了保证用户信息的安全,防止恶意的网站窃取数据。
Set-Cookie: key=value; domain=.example.com; path=/
复制代码同源政策规定,AJAX请求只能发给同源的网址,否则就报错。规避的几种方法
前端实现:
function jsonP (url, callbackName = 'callback') {
return new Promise((resolve, reject) => {
const scriptTag = document.createElement('script')
scriptTag.src = url + `?cb=${callbackName}`
scriptTag.setAttribute('type', 'text/javascript')
document.body.appendChild(scriptTag)
window[callbackName] = function jsonPCallback (data) {
if (data) resolve(data)
else reject(new Error('no data'))
document.body.removeChild(scriptTag)
}
})
}
jsonP('http://localhost:3000/jsonp').then(res => {
this.res = JSON.stringify(res)
})
// 返回数据样例
/**/ typeof callback === 'function' && callback({"data":{"name":"Tom"}});
复制代码服务端实现(以express为例):
// app.js 添加cb函数名字段,该参数为前端查询参数
app.set('jsonp callback name', 'cb')
// 直接使用jsonp返回即可
router.get('/jsonp', function(req, res) {
res.jsonp({data: {name: 'Tom'}})
});
// 前端请求实例:http://localhost:3000/jsonp?cb=callback
复制代码WebSocket是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。
基本实现(socket.io)
前端:
const socket = socketIo('http://localhost:3000/', {
query: {
auth: '123'
}
})
ocket.on('connect', () => {
this.connectStatus = `链接成功-${socket.id}`
})
socket.on('disconnect', () => {
this.connectStatus = '链接断开'
})
socket.on('connect_error', (err: Error) => {
this.connectStatus = `链接失败-${err.message}`
})
socket.on('Hi', (message: string) => {
this.message = message
})
复制代码服务端实现:
const io = require('socket.io')({
path: '/socket.io',
serveClient: false
});
io.on('connect', (socket) => {
// 校验跨域源信息
if (!['http://localhost:8080'].includes(socket.handshake.headers.origin)) {
return socket.disconnect()
}
socket.emit('Hi', 'Hello');
})
io.attach(server, {
pingInterval: 10000,
pingTimeout: 5000,
cookie: false
});
复制代码这类请求不会触发预检请求
请求携带的首部信息:
Origin: http://foo.example
复制代码请求响应首部信息:
Access-Control-Allow-Origin: http://foo.example
复制代码非简单请求会在正式请求之前,发送一个预检请求,用来询问服务器,是否可以跨域请求以及允许的请求方法,头部字段等。
预检请求携带的首部信息:
Origin: http://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
复制代码预检请求响应首部信息:
Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Expose-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
复制代码本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。