跨域

2022-10-15 计算机网络 大约 4 分钟

概念:浏览器使用 ajax,如果请求了的接口地址 和当前**打开的页面地址不同源**称之为跨域;

  1. 同源: 两个url协议域名端口三者均一致;
  2. 不同源;三个有一个不一同,则为不同源,称之为跨域;

# 跨域的解决方式

# cors(跨域资源共享)

目前最主流也是最简单的解决方案;

app.use((req, res) => {
  // 设置响应头
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.send('我跨域了');
});
1
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('开启成功');
    }
})
1
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-MethodsAccess-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>
1
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);
1
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>
1
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');
    }
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

本质:会动态的在页面的顶部创建一个script标签并设置src属性及callback参数,发送请求并解析函数调用之后会自动移出;

原理:

  • 设置script标签的src属性,向一个不同源的接口发送一个get请求;
  • src属性发送请求时,在参数中额外携带一个callback的参数,参数值是一个在页面中预先定于好的函数名。
  • 服务器接收到请求之后,获取callback的参数值。
  • 服务器将要响应的数据拼接成 函数调用格式,通过传参的方式将响应数据返回给浏览器

相关信息

  1. 用JSONP来解决跨域;必须是GET请求;
  2. callback 是发明jsonp技术的人提出的一个君子之约,只为固定写法。
  3. 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>
1
2
3
4
5
6
7

通过上面的代码中我们不难看出,src的属性值中有一个callback参数,值为我们要执行的函数的名字;

注意http链接为我的在线接口测试地址,当然你也可以使用;

上面的代码运行之后你会惊奇的发现Fn函数执行了,而且val为接口响应回来的数据;

这就是jsonp的跨域实现原理;

  1. src中用callback关键字作为参数,值为要执行的函数;
  2. 当响应成功时,响应回来的数据会作为参数传入Fn(responseData);

# JSONPCORS区别

  • CORS:
    • 服务器返回响应头,前端无需任何处理
    • 简单快捷,支持所有请求方式
  • JSONP
    • 浏览器:自定义响应回调函数,使用script标签的src请求
      • 利用浏览器的src属性没有跨域这一限制特点
    • 服务器:接收callback参数,返回函数调用
    • 处理复杂,并且只支持get请求
      • 原因:get请求参数直接在url后面拼接,而post请求参数是放在请求体中;
上次编辑于: 2023年7月4日 09:36