• 小满Vue3第四十六章(Proxy跨域)


    1.首先我们先了解一下什么是跨域

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

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

    例如 xxxx.com -> xxxx.com 存在跨域 协议不同

    例如 127.x.x.x:8001 -> 127.x.x.x:8002 存在跨域 端口不同

    例如 www.xxxx.com -> www.yyyy.com 存在跨域 域名不同

    2.如何解决跨域

    jsonp 这种方式在之前很常见,他实现的基本原理是利用了HTML里script元素标签没有跨域限制 动态创建script标签,将src作为服务器地址,服务器返回一个callback接受返回的参数

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

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

    1. {
    2. "Access-Control-Allow-Origin": "http://web.xxx.com" //可以指定地址
    3. }
    4. 复制代码
    1. {
    2. "Access-Control-Allow-Origin": "*" //也可以使用通配符 任何地址都能访问 安全性不高
    3. }
    4. 复制代码

    使用Vite proxy 或者 node代理 或者 webpack proxy 他们三种方式都是代理

    我们先创建一个接口使用express简单构建一下

    1. const express = require('express')
    2. const app = express()
    3. //创建get请求
    4. app.get('/xm',(req,res)=>{
    5. res.json({
    6. code:200,
    7. message:"请求成功"
    8. })
    9. })
    10. //端口号9001
    11. app.listen(9001)
    12. 复制代码

    我们使用vite项目的fetch 请求一下

    1. <script lang="ts" setup>
    2. import {ref,reactive } from 'vue'
    3. fetch('http://localhost:9001/xm')
    4. </script>
    5. 复制代码

     发现是存在跨域的,这时候我们就可以配合vite的代理来解决跨域 用法如下

    需要在vite.config.js/ts 进行配置

    1. export default defineConfig({
    2. plugins: [vue()],
    3. server:{
    4. proxy:{
    5. '/api':{
    6. target:"http://localhost:9001/", //跨域地址
    7. changeOrigin:true, //支持跨域
    8. rewrite:(path) => path.replace(/^\/api/, "")//重写路径,替换/api
    9. }
    10. }
    11. }
    12. })
    13. 复制代码

    fetch 替换/api 他会截取/api 替换成 target地址

    1. <script lang="ts" setup>
    2. import {ref,reactive } from 'vue'
    3. fetch('/api/xm')
    4. </script>
    5. 复制代码

     webpack proxy 和 node proxy 用法都类似

    3.vite proxy 原理解析

    vite源码地址github.com/vitejs/vite

    源码路径 vite/packages/vite/src/node/server/index.ts vite源码 发现他处理proxy 是调用了proxyMiddleware

    1. // proxy
    2. const { proxy } = serverConfig
    3. if (proxy) {
    4. middlewares.use(proxyMiddleware(httpServer, proxy, config))
    5. }
    6. 复制代码

    vite/packages/vite/src/node/server/middlewares/proxy.ts

    找到 proxyMiddleware 发现他是调用了 http-proxy这个库

    1. import httpProxy from 'http-proxy'
    2. export function proxyMiddleware(
    3. httpServer: http.Server | null,
    4. options: NonNullable<CommonServerOptions['proxy']>,
    5. config: ResolvedConfig
    6. ): Connect.NextHandleFunction {
    7. // lazy require only when proxy is used
    8. const proxy = httpProxy.createProxyServer(opts) as HttpProxy.Server
    9. 复制代码

    http-proxy npm地址 www.npmjs.com/package/htt…

    http-proxy 模块用于转发 http 请求,其实现的大致原理为使用 http 或 https 模块搭建 node 代理服务器,将客户端发送的请求数据转发到目标服务器,再将响应输送到客户端

    1. const http = require('http')
    2. const httpProxy = require('http-proxy')
    3. const proxy = httpProxy.createProxyServer({})
    4. //创建一个代理服务 代理到9001
    5. http.createServer((req,res)=>{
    6. proxy.web(req,res,{
    7. target:"http://localhost:9001/xm", //代理的地址
    8. changeOrigin:true, //是否有跨域
    9. ws:true //webSocetk
    10. })
    11. }).listen(8888)
    12. 复制代码

    9001服务

    1. const express = require('express')
    2. const app = express()
    3. //创建get请求
    4. app.get('/xm',(req,res)=>{
    5. res.json({
    6. code:200,
    7. message:"请求成功"
    8. })
    9. })
    10. //端口号9001
    11. app.listen(9001)
    12. 复制代码

    成功代理 访问8888端口代理9001的请求

  • 相关阅读:
    开源软件的影响力
    了解JS中的混个对象“类”
    学3D建模要注意什么问题?入行好几年,踩过的坑后的经验
    C#:Bitmap类使用方法—第1讲
    动态规划问题(三)
    [Power Query] 快速计算列
    Linux UWB Stack实现——FiRa会话状态机
    腾讯云2023年双十一优惠活动整理汇总
    Vue2 零基础入门 Vue2 零基础入门第三天 3.4 vue组件
    数据结构--java实现稀疏数组和队列
  • 原文地址:https://blog.csdn.net/qq1195566313/article/details/128081558