跨域
概念:浏览器使用
ajax
时,如果请求了的接口地址 和当前**打开的页面
地址不同源
**称之为跨域;
- 同源: 两个
url
协议、域名、端口三者均一致; - 不同源;三个有一个不一同,则为不同源,称之为跨域;
# 跨域的解决方式
# cors
(跨域资源共享)
目前最主流也是最简单的解决方案;
app.use((req, res) => {
// 设置响应头
res.setHeader('Access-Control-Allow-Origin', '*');
res.send('我跨域了');
});
2
3
4
5
express
的中间件cors
,它的作用是自动给每一个res设置默认请求头;
const express=require('express');
//中间件;
const cors=require('cors');
//创建服务器对象;
const app=express();
//使用中间件来设置默认请求头;
app.use(cors());
//注册路由;
app.get('/list',function (request,response) {
console.log('我被请求了==get');
response.send('我返回了');
});
app.post('/add',function (request,response) {
console.log('我被请求了==post');
response.send('我返回了')
})
//开启服务器,开始监听;
app.listen(8889,function (err) {
if (!err) {
console.log('开启成功');
}
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
工作原理:服务器在返回响应报文的时候,在响应头中设置一个允许的header ,让浏览器准许访问来自不同服务器上的指定资源;
res.setHeader('Access-Control-Allow-Origin', '*');
相关信息
简单请求(GET、POST、HEAD
)可以直接设置 Access-Control-Allow-Origin
解决跨域问题。但是非简单请求 (a
) 则还需要根据提示设置 Access-Control-Allow-Methods
和 Access-Control-Allow-Headers
# JSONP
核心原理:如果script标签的src属性的请求,服务器返回的是一个函数调用。则浏览器会执行这个函数;
# 示例代码一:
<!DOCTYPE html>
<html>
<script>
function doSomething(backData){
console.log("调用了");
console.log(backData);
}
</script>
<script src="http://127.0.0.1:3000/jsonpApi?callback=doSomething">
</script>
</html>
2
3
4
5
6
7
8
9
10
11
const express = require('express');
const app = express();
app.get('/jsonpApi', (req, res) => {
res.jsonp("x6");
});
app.listen(3000);
2
3
4
5
6
7
8
9
# 示例代码二:
<!DOCTYPE html>
<html>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<body>
<input type="button" value="jsonp跨域方案" class="jsonp">
</body>
<script>
$('.jsonp').click(function () {
$.ajax({
url: 'http://127.0.0.1:3000/jsonpApi',
data: {
name: 'rose',
friend: 'jack',
skill: '抗冻'
},
dataType: 'jsonp',//响应内容为jsonp格式的;
success(backData) {
console.log(backData);
}
})
})
</script>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const express = require('express')
const app = express()
app.get('/jsonpApi',(request,response)=>{
// 响应内容 jsonp的接口 返回数据用`jsonp`
response.jsonp({
msg:"请求成功",
code:200,
info:"欢迎再来"
})
})
app.listen(3000,(err)=>{
if(!err){
console.log('success');
}
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
本质:会动态的在页面的顶部创建一个script标签并设置src属性及callback参数,发送请求并解析函数调用之后会自动移出;
原理:
- 设置script标签的src属性,向一个不同源的接口发送一个get请求;
- src属性发送请求时,在参数中额外携带一个callback的参数,参数值是一个在页面中预先定于好的函数名。
- 服务器接收到请求之后,获取callback的参数值。
- 服务器将要响应的数据拼接成
函数调用格式
,通过传参的方式将响应数据返回给浏览器
相关信息
- 用JSONP来解决跨域;必须是GET请求;
- callback 是发明jsonp技术的人提出的一个
君子之约
,只为固定写法。 - callback属性值是预先定义的函数名,这个函数必须要在script标签之前定义。
# jsonp
跨域的实现原理
利用javascript里边的src属性的开放原则实现跨域:
<script>
function Fn(val) {
console.log(333)
console.log(val)
}
</script>
<script src="http://jsonplaceholder.typicode.com/posts?callback=Fn"></script>
2
3
4
5
6
7
通过上面的代码中我们不难看出,
src
的属性值中有一个callback
参数,值为我们要执行的函数的名字;注意:
http
链接为我的在线接口测试地址,当然你也可以使用;
上面的代码运行之后你会惊奇的发现Fn
函数执行了,而且val
为接口响应回来的数据;
这就是jsonp
的跨域实现原理;
- 在
src
中用callback
关键字作为参数,值为要执行的函数; - 当响应成功时,响应回来的数据会作为参数传入
Fn(responseData)
;
# JSONP
与CORS
区别
- CORS:
- 服务器返回响应头,前端无需任何处理
- 简单快捷,支持所有请求方式
- JSONP
- 浏览器:自定义响应回调函数,使用script标签的src请求
- 利用浏览器的src属性没有跨域这一限制特点
- 服务器:接收callback参数,返回函数调用
- 处理复杂,并且只支持get请求
- 原因:get请求参数直接在url后面拼接,而post请求参数是放在请求体中;
- 浏览器:自定义响应回调函数,使用script标签的src请求