前端工作问题或知识记录

发布于:2025-09-11 ⋅ 阅读:(15) ⋅ 点赞:(0)

前端场景问题

1、前端开发环境代理生产环境代理的本质区别。这两个地址代表了在不同环境下的代理目标


1. Nginx 配置文件中的 proxy_pass 地址

proxy_pass http://172.30.204.241:8372;

  • 代表什么:这个地址是 Nginx 反向代理最终目标地址
  • 用途:这个配置用于生产环境测试环境。当您的前端项目部署到服务器后,所有来自用户浏览器的 /chat-service 请求,都会被 Nginx 接收,然后无缝地转发到这个地址所指向的后端服务上。
  • 网络流向用户浏览器 -> Nginx 服务器 -> 后端服务(172.30.204.241:8372

这个地址通常是后端服务的真实内网 IP 和端口,对前端是完全透明的。

2. Vite 配置文件中的 proxy.target 地址

target: http://10.1.115.38:8370,

  • 代表什么:这个地址是 Vite 本地开发服务器代理目标地址
  • 用途:这个配置仅用于本地开发环境。当您在本地运行 npm run dev 时,您的浏览器会向本地的 localhost:3000(或您指定的端口)发起请求,Vite 就会将 /chat-service 请求代理到这个地址。
  • 网络流向本地浏览器 -> 本地 Vite 开发服务器 -> 后端服务(10.1.115.38:8370

为什么这两个地址不同?

这是因为运行环境不同,后端服务的地址也不同

  • Nginx 运行在服务器上,它访问后端服务时,后端可能位于同一个内网段,有自己的内网 IP(如 172.30.204.241)。
  • Vite 运行在您的本地电脑上,它需要访问服务器上的后端服务。所以,它使用的代理地址就是您服务器的公网或内网 IP(10.1.115.38),以及后端服务对外暴露的端口(8370)。

您提供的这两个配置是完全合理的,它们分别服务于不同的场景:前者解决生产环境的跨域问题,后者解决本地开发的跨域问题

您对这两个代理配置在不同环境下的作用还有疑问吗?







2、无头浏览器截图服务


步骤一:环境准备 (Setup)

首先,确保您的服务器上安装了 Node.jsnpm。如果还没有,请先安装。

然后,创建一个新的项目文件夹,并初始化它。

mkdir screenshot-service
cd screenshot-service
npm init -y

接着,安装您需要用到的核心库:express 用于创建 API 服务,puppeteer 用于控制无头浏览器。

npm install express puppeteer

步骤二:编写核心服务 (Coding)

创建一个名为 server.js 的文件,将以下代码复制进去。我已经为您添加了详细的注释,解释了每一部分的作用。

const express = require('express');
const puppeteer = require('puppeteer');
const app = express();
const PORT = 3001; // 您可以自定义端口

// 启用对 JSON 请求体的解析
app.use(express.json());

// 启用 CORS,允许您的前端项目访问
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*'); // 允许所有来源
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  next();
});

// 定义截图 API 接口
app.post('/api/screenshot', async (req, res) => {
  const { url } = req.body;

  if (!url) {
    return res.status(400).json({ error: 'URL is required' });
  }

  let browser;
  try {
    // 启动无头浏览器,添加 --no-sandbox 参数以避免权限问题
    browser = await puppeteer.launch({
      args: ['--no-sandbox', '--disable-setuid-sandbox']
    });
    
    const page = await browser.newPage();
    await page.setViewport({ width: 1920, height: 1080 });

    // 访问目标 URL 并等待页面加载完成
    await page.goto(url, { waitUntil: 'networkidle0' });

    // 等待 3D 渲染完成,可以根据实际情况调整时间
    // 这一步非常关键,确保所有模型和纹理都已加载
    await page.waitForTimeout(5000); 

    // 执行截图,并以 Base64 格式返回
    const screenshot = await page.screenshot({ encoding: 'base64' });

    // 返回图片数据给前端
    res.json({ imageUrl: `data:image/png;base64,${screenshot}` });

  } catch (error) {
    console.error('截图失败:', error);
    res.status(500).json({ error: 'Failed to capture screenshot' });
  } finally {
    if (browser) {
      await browser.close();
    }
  }
});

app.listen(PORT, () => {
  console.log(`Screenshot service running on port ${PORT}`);
});

步骤三:部署与运行 (Deployment)

  1. 上传代码:将整个 screenshot-service 文件夹上传到您的 Linux 服务器。
  2. 安装依赖:在服务器上进入该文件夹,再次运行 npm install
  3. 启动服务:使用 node 命令启动服务。
    node server.js
    
    为了让服务在后台持续运行,我建议您使用 pm2 等进程管理工具。
    npm install pm2 -g
    pm2 start server.js
    

步骤四:前端调用 (Frontend)

现在,您的截图服务已经部署并运行。您只需修改前端代码,向这个新服务发起请求。

// 在您的 Vue 或 React 项目中
const axios = require('axios');

const urlToCapture = "https://sup.3dsource.cn/#/preview?access_token=...";

axios.post('http://<您的服务器IP>:3001/api/screenshot', { url: urlToCapture })
  .then(response => {
    const imageUrl = response.data.imageUrl;
    // 使用 imageUrl 来显示图片,例如:
    const imgElement = document.createElement('img');
    imgElement.src = imageUrl;
    document.body.appendChild(imgElement);
  })
  .catch(error => {
    console.error('API 调用失败:', error);
  });

完成以上步骤,您就能实现一个可靠、高效的截图服务。

实现细节

这段代码能够实现网页截屏,主要是因为它利用了 Puppeteer 这个强大的库。

要理解这段代码的工作原理,可以从以下几个核心点来分析:

1. 启动一个“隐形”浏览器

browser = await puppeteer.launch({
  args: ['--no-sandbox', '--disable-setuid-sandbox']
});
  • puppeteer.launch(): 这个函数会启动一个真实的、完整的浏览器实例,但它是在后台运行,我们看不到界面,所以被称为“无头浏览器”(Headless Browser)。
  • args 参数: 这些参数是为了解决在某些 Linux 环境下运行时的权限问题,确保服务能够正常启动。

2. 模拟一个浏览器标签页

const page = await browser.newPage();
await page.setViewport({ width: 1920, height: 1080 });
  • browser.newPage(): 这行代码的作用是创建一个新的浏览器标签页。我们对网页的所有操作,比如访问 URL、点击、填写表单等,都是在这个 page 对象上执行的。
  • setViewport: 这行代码设置了浏览器窗口的大小,它决定了截图的分辨率。

3. 访问并等待网页加载

await page.goto(url, { waitUntil: 'networkidle0' });
  • page.goto(url): 这行代码指示无头浏览器访问您在 curl 请求中提供的 url
  • waitUntil: 'networkidle0': 这是一个非常重要的参数,它告诉 Puppeteer 等待页面加载完成的条件networkidle0 的意思是:当网络连接数在 500 毫秒内少于或等于 0 时,就认为页面加载完成。这个条件能够确保页面上的所有主要资源(如 HTML、CSS、JavaScript 文件)都已加载。

4. 等待 3D 模型渲染

await new Promise(resolve => setTimeout(resolve, 5000));

由于 3D 模型是动态加载和渲染的,即使网络连接空闲,模型本身可能还需要几秒钟才能完全显示出来。这段代码的作用就是暂停执行 5 秒钟,给 3D 模型预留充足的渲染时间,确保截取的是完整的、已渲染好的画面。

5. 执行截屏并返回数据

const screenshot = await page.screenshot({ encoding: 'base64' });
res.json({ imageUrl: `data:image/png;base64,${screenshot}` });
  • page.screenshot(): 这是实现截屏的核心方法。它会截取当前浏览器标签页的完整画面,并将其转换为 Base64 编码的字符串。
  • res.json(): 最后,后端将这个 Base64 字符串作为 JSON 数据的一部分返回给前端,前端就可以直接解析并显示这张图片了。

简而言之,这段代码就像一个在服务器上工作的“自动化虚拟用户”。它会打开一个隐形的浏览器,访问指定的网页,等待页面内容(特别是 3D 模型)加载并渲染好,然后精准地拍下一张照片,最后将照片数据传回给您。


网站公告

今日签到

点亮在社区的每一天
去签到