跨域
同源限制
- 两个网页中协议,域名和端口号都相同则是同一个源;如果有一个不同则是不同源。
- 例如,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="https://juejin.cn/post/xxx">
<link href="https://juejin.cn/post/xxx"></link>
<script src="https://juejin.cn/post/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'},//get请求中的查询条件
dataType: 'jsonp',//类型
jsonpCallback: 'foo'//请求成功后执行的回调函数名
});
==>等同于
let script = document.createElement('script');
//script标签的src属性是下图中的URL地址
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})`;//回调函数foo(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;//端口号3000
server_name localhost;//域名,本机就是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;
//匹配到根目录/时(这里是localhost:3000)会转发到index.html或index.htm
location / {
root html;//根目录 ==> html目录
index index.html index.htm;
}
//匹配到以api/getData开头的请求(这里是我发送的请求)会转发到http://localhost:3000/api/getData
location /api/getData {
proxy_pass http://localhost:3000/api/getData;
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END






















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)