跨域
同源限制
- 两个网页中协议,域名和端口号都相同则是同一个源;如果有一个不同则是不同源。
- 例如,www.example.com/api/data 这个网址,它的协议是http://,域名是www.example.com ,端口是80;http协议默认端口是80,https默认端口是443
http://www.example.com/api/query 同源
http://example.com/api/data 不同源(域名不同)
http://www.example.com:300/api/data 不同源(端口不同)
https://www.example.com/api/data 不同源(协议不同)
1. 无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB
2. 无法接触非同源网页的 DOM
3. 无法向非同源地址发送 AJAX 请求(可以发送,但浏览器会拒绝接受响应)
跨域
- 跨域指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制。下面是端口号不同的跨域

<img src="xxx">
<link href="xxx"></link>
<script src="xxx"></script> ==> JSONP解决跨域
跨域常用解决方案
JSONP方式
- 仅支持GET请求,本质上就是插入一个script标签
- 使用JSONP解决跨域需要引入jQuery,需要前后端一起才能解决跨域
- 前端代码
<body>
<button onclick="getJsonp()">jsonp解决跨域</button>
<script>
function getJsonp() {
$.ajax({
url: 'http://localhost:3000/api/jsonp',
data: {name: 'abc'},
dataType: 'jsonp',
jsonpCallback: 'foo'
});
==>等同于
let script = document.createElement('script');
script.setAttribute('src', 'http://localhost:3000/api/jsonp?callback=foo&name=abc&_=1623667312766');
document.body.appendChild(script);
}
function foo(data) {
console.log(data);
}
</script>
</body>
- JSONP请求发送的地址等同于下图的地址,该地址中有一个callback回调函数,后端可以通过req.query.callback获取回调函数名

app.get('/api/jsonp', (req, res) => {
let data = JSON.stringify({name: 'json数据'});
let callback = `${req.query.callback}(${data})`;
res.send(callback);
});
CORS方式
- CORS 是一个 W3C 标准,全称是“跨域资源共享”(Cross-origin resource sharing)。它允许浏览器向跨域的服务器,发出XMLHttpRequest请求,从而克服了 AJAX 只能同源使用的限制
let cors = function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE');
res.setHeader('Access-Control-Allow-Headers', '*');
next();
};
app.use(cors);
app.put('/api/getData', (req, res) => {
res.send('hello');
});
简单请求
- 请求方法是以下三种方法之一
HEAD
GET
POST
- HTTP 的头信息不超出以下几种字段
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
非简单请求
- 非简单请求是那种对服务器提出特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。
- 非简单请求的 CORS 请求,会在正式通信之前,增加一次 HTTP 查询请求,称为“预检”请求(预请求OPTIONS)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些 HTTP 方法和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。这是为了防止这些新增的请求,对传统的没有 CORS 支持的服务器形成压力,给服务器一个提前拒绝的机会,这样可以防止服务器收到大量DELETE和PUT请求。

Nginx方式
- 需要将你的index.html页面放到nginx中的html文件中
- 配置nginx中的conf目录中的nginx.conf文件
server {
listen 3000;
server_name localhost;
add_header Access-Control-Allow-Origin $http_origin always;
add_header Access-Control-Allow-Credentials true always;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS' always;
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep- Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content- Type,Authorization' always;
location / {
root html;
index index.html index.htm;
}
location /api/getData {
proxy_pass http:
}