
主要是出于浏览器的同源策略限制,它是浏览器最核心也最基本的安全功能。
当一个请求url的 协议、域名、端口 三者之间任意一个与当前页面url不同即为跨域。
例如 xxxx.com -> xxxx.com 存在跨域 协议不同
例如 127.x.x.x:8001 -> 127.x.x.x:8002 存在跨域 端口不同
例如 www.xxxx.com -> www.yyyy.com 存在跨域 域名不同
jsonp 这种方式在之前很常见,他实现的基本原理是利用了HTML里script元素标签没有跨域限制 动态创建script标签,将src作为服务器地址,服务器返回一个callback接受返回的参数
- 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 允许跨域资源共享 需要后端设置
- {
- "Access-Control-Allow-Origin": "http://web.xxx.com" //可以指定地址
- }
- 复制代码
- {
- "Access-Control-Allow-Origin": "*" //也可以使用通配符 任何地址都能访问 安全性不高
- }
- 复制代码
使用Vite proxy 或者 node代理 或者 webpack proxy 他们三种方式都是代理
我们先创建一个接口使用express简单构建一下
- const express = require('express')
- const app = express()
-
- //创建get请求
- app.get('/xm',(req,res)=>{
- res.json({
- code:200,
- message:"请求成功"
- })
- })
- //端口号9001
- app.listen(9001)
- 复制代码

我们使用vite项目的fetch 请求一下
- <script lang="ts" setup>
- import {ref,reactive } from 'vue'
- fetch('http://localhost:9001/xm')
- </script>
- 复制代码

发现是存在跨域的,这时候我们就可以配合vite的代理来解决跨域 用法如下
需要在vite.config.js/ts 进行配置
- export default defineConfig({
- plugins: [vue()],
- server:{
- proxy:{
- '/api':{
- target:"http://localhost:9001/", //跨域地址
- changeOrigin:true, //支持跨域
- rewrite:(path) => path.replace(/^\/api/, "")//重写路径,替换/api
- }
- }
- }
- })
- 复制代码
fetch 替换/api 他会截取/api 替换成 target地址
- <script lang="ts" setup>
- import {ref,reactive } from 'vue'
- fetch('/api/xm')
- </script>
- 复制代码
webpack proxy 和 node proxy 用法都类似
vite源码地址github.com/vitejs/vite
源码路径 vite/packages/vite/src/node/server/index.ts vite源码 发现他处理proxy 是调用了proxyMiddleware
- // proxy
- const { proxy } = serverConfig
- if (proxy) {
- middlewares.use(proxyMiddleware(httpServer, proxy, config))
- }
- 复制代码
vite/packages/vite/src/node/server/middlewares/proxy.ts
找到 proxyMiddleware 发现他是调用了 http-proxy这个库
- import httpProxy from 'http-proxy'
- export function proxyMiddleware(
- httpServer: http.Server | null,
- options: NonNullable<CommonServerOptions['proxy']>,
- config: ResolvedConfig
- ): Connect.NextHandleFunction {
- // lazy require only when proxy is used
- const proxy = httpProxy.createProxyServer(opts) as HttpProxy.Server
- 复制代码
http-proxy npm地址 www.npmjs.com/package/htt…
http-proxy 模块用于转发 http 请求,其实现的大致原理为使用 http 或 https 模块搭建 node 代理服务器,将客户端发送的请求数据转发到目标服务器,再将响应输送到客户端
- const http = require('http')
-
- const httpProxy = require('http-proxy')
-
- const proxy = httpProxy.createProxyServer({})
-
- //创建一个代理服务 代理到9001
- http.createServer((req,res)=>{
- proxy.web(req,res,{
- target:"http://localhost:9001/xm", //代理的地址
- changeOrigin:true, //是否有跨域
- ws:true //webSocetk
- })
- }).listen(8888)
- 复制代码
9001服务
- const express = require('express')
- const app = express()
-
- //创建get请求
- app.get('/xm',(req,res)=>{
- res.json({
- code:200,
- message:"请求成功"
- })
- })
- //端口号9001
- app.listen(9001)
- 复制代码
成功代理 访问8888端口代理9001的请求
