window中借助nginx配置vite+vue项目的反向代理步骤

在官网下载好nginx的安装包后,解压后

在这里插入图片描述

CMD打开

start nginx 是启动命令
nginx -s stop 停止服务
nginx -s reload 如果重写了nginx.conf文件,要执行这条命令

正常情况下

成功启动和成功停止服务长这样
在这里插入图片描述

错误情况&解决

  • 如果nginx -s stop失败

nginx: [error] CreateFile() “V:\Web\16 nginx\nginx/logs/nginx.pid” failed (2: The system cannot find the file specified)

借助命令

查看与nginx相关的端口
tasklist /fi "imagename eq nginx.exe"

停止nginx进程
taskkill /f /t /im "nginx.exe"

在这里插入图片描述

在conf文件中看它的默认端口

比如我这里就不是80端口,而是5000端口。

在这里插入图片描述

在浏览器地址栏中输入 http://localhost:5000
正常情况下是nginx默认的页面(我这里是已经部署在上面了)
在这里插入图片描述

vue项目部署

在vs code中 pnpm install build

在这里插入图片描述

文件目录中会出现dist文件夹,把dist文件夹下的所有文件【替代】nginx html目录下的所有文件

在这里插入图片描述

因为vue项目中,我使用了vite进行反向代理,但是在实际项目上线后是没有用的,所以要借助nginx。

vite反向代理的逻辑

vite.config.js

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
// import basicSsl from '@vitejs/plugin-basic-ssl'

export default defineConfig({
  server:{
    // host: '0.0.0.0',
    // https: true,
    proxy: {
      '/binance':{
        target: 'https://api.binance.com',
        changeOrigin: true,
        // secure: true,  // 确保代理使用 HTTPS 请求
        // protocolRewrite: 'https',
        rewrite: (path) => path.replace(/^\/binance/, '')
      },
      '/rootdata':{
        target: 'https://api.rootdata.com/open/ser_inv',
        changeOrigin: true,
        rewrite: (path)=>path.replace(/^\/rootdata/, ''),
        secure: true  // 确保代理使用 HTTPS 请求
      },
      '/gecko':{
        target: 'https://api.coingecko.com/api/v3/simple/price',
        changeOrigin: true,
        // secure: false,  // 确保代理使用 HTTPS 请求
        // protocolRewrite: 'https',
        rewrite: (path) => path.replace(/^\/gecko/, '')
      },
      '/atguigu': {
        target: 'http://sph-api.atguigu.cn',
        changeOrigin: true,
        // secure: false,  // 确保代理使用 HTTPS 请求
        // protocolRewrite: 'https',
        rewrite: (path) => path.replace(/^\/atguigu/, '')
      }
    }
  },
  plugins: [
    vue(),
    // basicSsl()
  ],
  resolve: {
    alias: {
      "@": path.resolve("./src") // 相对路径别名配置,使用 @ 代替 src
    }
  }
})

vue文件

import axios from 'axios';
async function getBTCPrice() {
  try {
    const response = await axios.get('/binance/api/v3/ticker/price', {
      params: { symbol: 'BTCUSDT' }
    });
    console.log('当前 BTC 价格:', response);
  } catch (error) {
    console.error('获取价格时出错:', error);
  }
}

const test = ()=> {
  getBTCPrice()
}

nginx.conf

这个文件中配置反向代理

源文件删除所有的注释其实就几行:

worker_processes  1;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;

    keepalive_timeout  65;


    server {
        listen       5000;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
            try_files $uri $uri/ /index.html;
        }

        location /other/ {
            root   html;
            index  index.html index.htm;
            try_files $uri $uri/ /index.html;
        }

        location /template {
            rewrite  ^.+template/?(.*)$ /$1 break;
            proxy_pass  http://192.168.245.203:10001;
            proxy_redirect off;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         }

      
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

}

以 /atguigu 这个路径为例

① nginx.conf中添加下图这句话,注意路径加斜杠表示/atguigu这个路径最后没有(https://blog.youkuaiyun.com/yavlgloss/article/details/139503686)。②在CMD中 nginx -s reload。③在页面中发现网络请求成功
在这里插入图片描述
在这里插入图片描述

<think> 我们之前已经讨论过在Spring Boot + Vue3中使用iframe嵌入第三方页面的跨域问题,并给出了解决方案。现在用户再次提出相同的问题,可能是因为之前的解决方案需要更详细的解释,或者用户在实际操作中遇到了问题。我们将再次详细解释解决方案,并确保覆盖所有关键点。 ### 问题分析 在开发环境中,Vue3应用运行在`http://localhost:5173`,而通过iframe嵌入的第三方页面可能位于其他域名(如`https://example.com`)。由于浏览器的同源策略,直接嵌入会导致跨域问题,表现为页面无法加载或无法与iframe内容交互。 ### 解决方案 #### 1. 后端配置(Spring Boot): 允许前端域访问API(如果前端需要与后端通信) 虽然iframe的跨域问题主要在前端解决,但若前端需要从Spring Boot获取数据,则需配置CORS。 ```java // 在Spring Boot中配置CORS @Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:5173") // Vue开发服务器地址 .allowedMethods("*") .allowedHeaders("*") .allowCredentials(true); } } ``` #### 2. 前端代理(Vite): 解决iframe加载第三方页面的跨域 使用Vite的代理功能,将特定路径的请求转发到第三方服务器。这样,iframe的src属性使用相对路径(同源),由Vite服务器代理请求。 ```javascript // vite.config.js import { defineConfig } from 'vite'; export default defineConfig({ // ...其他配置 server: { proxy: { // 代理规则:所有以/third-party开头的请求都转发到目标第三方服务器 '/third-party': { target: 'https://example.com', // 第三方系统的域名 changeOrigin: true, // 改变请求头中的host为目标地址 rewrite: (path) => path.replace(/^\/third-party/, '') // 去掉路径中的代理标识 } } } }); ``` #### 3.Vue组件中使用代理路径 在iframe的src属性中,使用代理路径(例如`/third-party/path/to/page`)代替完整的第三方URL。 ```vue <template> <iframe src="/third-party/path/to/page" frameborder="0" style="width: 100%; height: 600px" /> </template> ``` #### 4. 处理与iframe的通信(使用postMessage) 当需要与iframe内的页面进行通信时,使用`window.postMessage`和`message`事件监听。 ```vue <script setup> import { onMounted, onUnmounted } from 'vue'; // 接收来自iframe的消息 const handleMessage = (event) => { // 重要:验证消息来源 if (event.origin !== 'https://example.com') return; console.log('Received message from iframe:', event.data); }; onMounted(() => { window.addEventListener('message', handleMessage); }); onUnmounted(() => { window.removeEventListener('message', handleMessage); }); // 向iframe发送消息 const sendMessageToIframe = () => { const iframe = document.querySelector('iframe'); if (iframe && iframe.contentWindow) { // 发送消息到指定的源 iframe.contentWindow.postMessage({ type: 'GREETING', data: 'Hello' }, 'https://example.com'); } }; </script> ``` ### 解决方案解释 1. **CORS配置**:确保Spring Boot后端允许Vue前端域的请求,避免API请求跨域问题。 2. **Vite代理**:通过代理,将特定路径的请求转发到第三方服务器。浏览器看到的是同源请求(因为请求发往Vite开发服务器),而Vite在服务器端将请求转发到目标服务器,绕过浏览器跨域限制。 3. **iframe使用代理路径**:在iframe的src中使用代理路径(如`/third-party/xxx`),这样浏览器会向Vite服务器请求,Vite代理到真实地址。 4. **跨文档消息通信**:使用`postMessage`和`message`事件监听实现跨域通信,但必须验证消息来源以防止安全风险。 ### 常见问题及解决 - **问题1:浏览器控制台提示`Refused to display in a frame because it set 'X-Frame-Options' to 'sameorigin'`** 这表示目标页面不允许被嵌入到iframe中。需要第三方服务器设置响应头`X-Frame-Options`为`ALLOW-FROM http://localhost:5173`或`Content-Security-Policy`包含`frame-ancestors http://localhost:5173`。如果无法控制第三方服务器,则无法解决。 - **问题2:代理后仍然无法加载** 检查Vite代理配置是否正确,特别是`rewrite`函数是否去除了代理前缀。使用浏览器开发者工具查看网络请求,确认请求是否被正确转发。 - **问题3:通信失败** 确保在发送消息时指定了正确的目标源(`postMessage`的第二个参数),并且在接收消息时验证了`event.origin`。 ### 生产环境注意事项 开发环境使用Vite代理,生产环境应使用Nginx或类似的反向代理来处理代理请求。例如Nginx配置: ```nginx location /third-party/ { proxy_pass https://example.com/; # 注意末尾的斜杠 proxy_set_header Host example.com; proxy_set_header X-Real-IP $remote_addr; # 其他代理设置... } ``` 然后,在生产环境中,Vue应用的iframe仍然使用`/third-party/path/to/page`作为src。 --- §§相关问题§§: 1. 第三方页面设置了`X-Frame-Options: DENY`,如何绕过限制? 2. 如何确保通过`postMessage`进行跨域通信的安全性? 3.Vue3中,如何优雅地封装iframe组件以实现复用? 4. 除了代理,还有哪些方法可以解决iframe跨域问题? </think> ### 解决方案:Spring Boot + Vue3 中解决 iframe 跨域问题 在本地开发环境中使用 iframe 嵌入第三方页面时,需要解决三个关键问题:**页面加载跨域**、**通信跨域**和**安全策略限制**。以下是完整解决方案: --- #### 1. 后端配置(Spring Boot):解决 API 跨域 在 Spring Boot 中配置全局 CORS 策略: ```java // src/main/java/com/example/config/CorsConfig.java import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:5173") // Vue 开发服务器 .allowedMethods("*") .allowedHeaders("*") .exposedHeaders("Custom-Header") // 暴露自定义头部 .allowCredentials(true) .maxAge(3600); } } ``` #### 2. 前端配置Vue3):代理第三方请求 在 `vite.config.js` 中设置代理规则: ```javascript // vite.config.js export default defineConfig({ server: { proxy: { // 代理所有以 /external 开头的路径 '/external': { target: 'https://third-party.com', changeOrigin: true, rewrite: (path) => path.replace(/^\/external/, ''), headers: { // 添加自定义头部解决特定限制 'X-Forwarded-Host': 'localhost:5173' }, // 处理 Cookie cookieDomainRewrite: 'localhost' } } } }) ``` #### 3. Vue 组件中使用 iframe 使用代理路径加载第三方页面: ```vue <template> <!-- 使用代理路径避免跨域 --> <iframe ref="thirdPartyFrame" src="/external/path/to/page" @load="handleIframeLoad" /> </template> <script setup> import { ref } from 'vue'; const thirdPartyFrame = ref(null); // iframe 加载完成回调 const handleIframeLoad = () => { console.log('iframe loaded'); sendMessageToIframe(); }; // 向 iframe 发送消息 const sendMessageToIframe = () => { const iframeWindow = thirdPartyFrame.value.contentWindow; iframeWindow.postMessage( { type: 'AUTH_TOKEN', token: 'secure-jwt' }, 'https://third-party.com' // 必须指定目标域 ); }; // 接收 iframe 消息 window.addEventListener('message', (event) => { // 严格验证来源 if (event.origin !== 'https://third-party.com') return; if (event.data.type === 'USER_ACTION') { console.log('Received action:', event.data.payload); } }); </script> ``` #### 4. 处理安全策略限制(可选) 针对 `X-Frame-Options` 限制的解决方案: ```java // Spring Boot 控制器添加响应头覆盖 @GetMapping("/frame-proxy") public ResponseEntity<String> proxyFrame() { return ResponseEntity.ok() .header("X-Frame-Options", "ALLOW-FROM http://localhost:5173") .body(/* 代理内容 */); } ``` --- ### 关键原理详解 1. **跨域资源共享(CORS)** - Spring Boot 的 `CorsConfig` 允许前端域的跨域请求 - `allowCredentials(true)` 启用 Cookie 传递 - `exposedHeaders` 暴露自定义头部给前端 2. **开发服务器代理** - Vite 将 `/external/xxx` 代理到 `https://third-party.com/xxx` - `changeOrigin: true` 修改请求头中的 Host - `cookieDomainRewrite` 解决跨域 Cookie 问题 3. **跨文档通信安全** - `postMessage` 必须指定精确的目标域 (`targetOrigin`) - 接收方严格验证 `event.origin` - 使用 JWT 等安全机制代替直接传递敏感数据 4. **安全策略覆盖** - 通过后端代理重写 `X-Frame-Options` 头部 - 或使用 CSP 策略:`Content-Security-Policy: frame-ancestors 'self' localhost:5173` --- ### 常见问题排查表 | 问题现象 | 解决方案 | |---------|---------| | `Blocked by X-Frame-Options` | 配置反向代理重写响应头 | | `Invalid CORS request` | 检查 Spring Boot 的 allowedOrigins 配置 | | Cookie 丢失 | Vite 代理开启 `cookieDomainRewrite` | | `postMessage` 无效 | 验证目标域是否精确匹配 | | iframe 内容加载不全 | 确保第三方资源路径使用相对路径 | --- ### 生产环境注意事项 1. **反向代理配置** (Nginx 示例): ```nginx location /external/ { proxy_pass https://third-party.com/; proxy_cookie_domain third-party.com your-domain.com; proxy_set_header X-Forwarded-Host $host; # 重写安全头部 proxy_hide_header X-Frame-Options; add_header X-Frame-Options "ALLOW-FROM https://your-domain.com"; } ``` 2. **安全增强措施**: - 使用 CSP 代替 `X-Frame-Options` - 为 `postMessage` 添加消息签名验证 - 限制 iframe 的 `sandbox` 属性 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值