同源策略:客户端基本安全要求,需要同时满足:协议、域名、端口都得相同
注:http://127.0.0.1:7001 与 http://localhost:7001 域名不同,跨域了
受同源限制:动态数据
1. Ajax(客户端发起请求)
2. Cookie(存储在客户端)
3. localStorage:永久性客户端数据缓存
4. sessionStorage:客户端数据缓存
5. indexDB:客户端数据库
不受同源限制:静态资源
1. Session(存储在服务器端)
2. script:src属性可以指定外部的js文件
3. img:src属性可以指定外部的图片文件
4. link:href属性可以指定外部的css文件
5. iframe/audio/radio:src属性可以引入外部文件
跨域解决办法:JSONP、CORS、Proxy
1. Proxy
1. 代理服务器。任何服务器都可以配置成代理服务器
2. 目标服务器。需要请求的服务器端
以下是将vite配置成代理服务器的配置
创建文件:vite.config.js,在该文件内进行配置,代码如下:
import { defineConfig } from "vite";
export default defineConfig({
// 将vite配置成代理服务器
server: {
proxy: {
// 带选项写法:
//http://localhost:5173/api/bar->http://jsonplaceholder.typicode.com/bar
"/api": {
target: "http://xxx.xxx.x.xx:7001", //目标服务器地址
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ""),
},
},
},
});
原理:同源策略是客户端的要求
2. CORS
Cross-Origin Resource Sharing:跨域资源共享
2.1 实现
在Nodejs中,可以通过中间件来实现CORS跨域处理,步骤如下:
1. 在后端安装依赖包:cnpm i egg-cors --save
2. config/plugin.js中配置,代码如下:
// config/plugin.js
cors : {
enable: true,
package: 'egg-cors',
};
3. config/config.default.js中配置,代码如下:
// config/config.default.js
config.cors = {
origin: '*', // 允许跨域的源,可以指定源,也可以使用通配符*来允许所有的源
allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH', // 允许请求的方式
credentials:true, //设置跨域是否允许携带Cookie(凭证)
};
2.2 跨域是否携带凭证
1. 前端配置:instance.js
// CORS处理跨域
baseURL: "http://192.168.2.13:7001", // 请求服务器时的基础路径,后面发起请求时自动携带它
// 跨域请求时是否带凭证 CORS
withCredentials: true, //默认false不允许
将Vite项目配置成使用局域网IP地址作为服务器访问地址,vite.config.js
server: {
//将Vite项目配置成使用局域网IP地址作为服务器访问地址,可以方便CORS跨域处理
// 服务器基本配置
host: "xxx.xxx.x.xx", //本机IP地址
port: xx, //设置端口号
}
2. 后端配置:
a. 指定具体的前端域名。config/config.default.js中配置,代码如下:
// config/config.default.js
config.cors = {
origin: 'http://上面代码中的IP地址和端口', //允许跨域携带凭证时,需要指定具体的前端域名
allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH', // 允许请求的方式
credentials:true, //设置跨域是否允许携带Cookie(凭证)
};
b. 允许跨域携带凭证(Cookie),上面代码已配置过。credentials : true
对跨域携带凭证的理解:比如,当用户在登录页面登录完成后,需要跳转到个人中心页面,如果CORS允许跨域携带凭证,则会自动携带上该域名下的会话信息。
3. JSONP
1. 原理:script标签不受同源限制,可以引入文件(只要响应的是js代码的文件)
2. 优点:兼容性好、轻便且高效
3. 缺点:只能获取数据,不能提交数据
理解:它通过在页面上动态创建一个script标签,该标签引用了一个跨域的js脚本文件,而该文件的内容应该是一个JavaScript函数调用。例如:
<script src="http://127.0.0.1:7001/users?_callback=fn"></script>
这个函数会将需要传输的数据作为参数传入,服务器则将数据封装在该函数的调用中,以此完成跨域数据传输。使用:在js中写一个函数,使用形参来接收该JSONP文件,根据文件形式来进行操作,比如说显示在当前页面中。