什么是跨域
请求如果触发了同源策略的话,会出现跨域的情况
最初,它的含义是指,A网页设置的 Cookie,B网页不能打开,除非这两个网页"同源"。所谓"同源"指的是"三个相同"。
协议相同
域名相同
端口相同
举例来说, www.example.com/dir/page.ht… 这个网址,协议是http:// ,域名是 www.example.com ,端口是80 (默认端口可以省略)。它的同源情况如下。
- www.example.com/dir2/other.… :同源
- example.com/dir/other.h… :不同源(域名不同)
- v2.www.example.com/dir/other.h… :不同源(域名不同)
- www.example.com:81/dir/other.h… :不同源(端口不同)
目的
同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。
设想这样一种情况:A网站是一家银行,用户登录以后,又去浏览其他网站。如果其他网站可以读取A网
站的 Cookie,会发生什么?
很显然,如果 Cookie 包含隐私(比如存款总额),这些信息就会泄漏。更可怕的是,Cookie 往往用来 保存用户的登录状态,如果用户没有退出登录,其他网站就可以冒充用户,为所欲为。因为浏览器同时还规定,提交表单不受同源政策的限制。
由此可见,"同源政策"是必需的,否则 Cookie 可以共享,互联网就毫无安全可言了。
限制范围
随着互联网的发展,"同源政策"越来越严格。目前,如果非同源,共有三种行为受到限制。
(1) Cookie、LocalStorage 和 IndexDB 无法读取。
(2) DOM 无法获得。
(3) A JAX 请求不能发送。
虽然这些限制是必要的,但是有时很不方便,合理的用途也受到影响。下面,我将详细介绍,如何规避上面三种限制。
解决方案
JSONP
根据之前的结局方案,需要前后端配合
静态网页的html
<!--
因为 服务器内做了配置, 只要是以 '/static' 开头的访问都会去到 '/client' 这个目录内
具体配置需要查看 index.js 1.1 步 开启静态资源
-->
<script>
function qwe(res) {
console.log('我是这个函数的内部代码')
console.log(res)
}
</script>
<script src="http://localhost:8081/a?callback=qwe">
//qwe是函数
</script>
需要接口服务器配合
server.get('/a', (req, res) => {
const { callback } = req.query
// console.log(`${callback}({code:1,msg:'请求成功'})`)
res.send(`${callback}({code:1,msg:'请求成功'})`)
})
CORS跨域
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的
AJAX通信没有差别,代码完全一样。浏览器一旦发现A JAX请求跨源,就会自动添加一些附加的头信息,
有时还会多出一次附加的请求,但用户不会有感觉。
因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
注意:写到接口服务器上 给谁添加CORS方法
//1.导入第三方库
const cors = require('cors')
//2.使用
server.use(cors())
const express = require('express')
//1.导入第三方库
const cors = require('cors')
const server = express()
//2.使用
server.use(cors())
server.get('/list', (req, res) => {
res.send({
code: 1,
msg: '请求成功'
})
})
server.post('/info', (req, res) => {
res.send({
code: 1,
msg: '请求成功'
})
})
server.listen('8081', () => console.log('接口服务器开启成功'))
axios
主要思路
通过服务其与服务器之间传递 就不会触发同源策略
比如8080 访问 8081 会触发同源策略
axios 访问自己的服务器 自己的服务器 去访问8081服务器 拿到值之后 通过自己的服务器返回给自己的8080
请求浏览器8080
const express = require('express')
const axios = require('axios')
const server = express()
server.use('/static', express.static('./client'))
server.get('/list', (req, res) => {
console.log('如果我执行了, 说明前端的代码是请求我的')
/**
* node 中 需要借助 axios 帮助我们发送请求, 第三方包的流程: 下载 导入 按照文档使用
*
* 安装命令: npm i axios
*/
axios({
method: 'GET',
url: 'http://localhost:8081/list'
}).then(result => {
// console.log(result.data)
res.send(result.data)
})
})
server.listen('8080', () => console.log('静态资源服务器开启成功'))
**不进行跨域 **
// 前端的代码, 发送一个请求
function myAjax1() {
const xhr = new XMLHttpRequest()
// xhr.open("GET", "http://localhost:8081/list");
xhr.open('GET', '/list')//通过自己的服务其拿
xhr.onload = function () {
console.log(JSON.parse(xhr.responseText))
}
xhr.send()
}
myAjax1()