跨域

浏览器具有同源策略的限制,它是浏览器最核心也最基本的安全功能。

当一个请求url的 协议、域名、端口,三者之间任意一个与当前页面url不同,都会造成跨域。

例如:

  • http://xxxx.comhttps://xxxx.com存在跨域,因为协议不同
  • 127.x.x.x:8001 → 127.x.x.x:8002存在跨域,因为端口不同
  • www.xxxx.comwww.yyyy.com存在跨域,因为域名不同

解决跨域

jsonp

老方案,利用了HTML里script元素标签没有跨域限制的基本原理。

动态创建script标签,将src作为服务器地址,服务器返回一个callback接受返回的参数。

只能使用GET请求。

1
2
3
4
5
6
7
8
9
10
11
12
function clickButton() {
let obj, s
obj = { "table":"products", "limit":10 }; //添加参数
s = document.createElement("script"); //动态创建script
s.src = "接口地址xxxxxxxxxxxx" + JSON.stringify(obj);
document.body.appendChild(s);
}
//与后端定义callback名称
function myFunc(myObj) {
//接受后端返回的参数
document.getElementById("demo").innerHTML = myObj;
}

CORS

设置CORS允许跨域资源共享,需要后端设置。

1
2
3
4
5
6
7
{
"Access-Control-Allow-Origin": "http://web.xxx.com" //可以指定地址
}

{
"Access-Control-Allow-Origin": "*" //也可以使用通配符,任何地址都能访问,但安全性不高,而且不能使用cookie
}

proxy代理

Vite proxy、node代理或webpack proxy,都是代理。

用node模拟一个简单的接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const express = require('express')
const app = express()

// 创建get请求
// req接收前端传的参数
// res给前端返回参数
app.get('/omg',(req,res)=>{
res.json({
code:200,
message:"请求成功"
})
})
// 端口号9001
app.listen(9001,()=> {
console.log("监听")
})

前端发送请求:

1
2
3
4
<script lang="ts" setup>
import {ref,reactive } from 'vue'
fetch('http://localhost:9001/omg')
</script>

这样直接请求会发生跨域问题,因为后端服务和前端服务的端口不一致

所以需要在vite.config.ts里配置代理:

1
2
3
4
5
6
7
8
9
10
11
12
export default defineConfig({
server: {
proxy: {
"/api": {
// 后端服务的地址
target: "http://localhost:9001",
// 请求的时候使用/api即可,vite会将其替换成""
rewrite: (path)=> path.replace(/^\/api/, "")
}
}
}
})

再次发送请求:

1
2
3
4
<script lang="ts" setup>
import {ref,reactive } from 'vue'
fetch('/api/omg')
</script>

proxy代理只适用于开发环境,程序上线后没有node环境,所以无法代理。若有需要,可以使用nginx。