前端小白记录一次跨域问题的解决|面试可参考

112 阅读4分钟

前言

跨域不仅是开发中常常遇到的问题,还是面试常考内容😋。但跨域的场景比较复杂,gpt也不能很好的解释(只会吐八股,所以我想写一篇文章专门记录一下在开发中遇到的一次跨域问题,从原理到解决方案一一步步产出。

叠甲🙇:第一次写技术文章,必然是存在纰漏的,希望评论区能友好指出,保持掘金的良好氛围❤️

还原场景

W同学🧑‍🎓在umi中进行了如下配置:

import { defineConfig } from "umi";

export default defineConfig({
  ...
  proxy: {
    "/api": {
      target: "http://test.example.com",
      changeOrigin: true,
      pathRewrite: { '^/api': '' },
    },
  },
});

该配置的作用是在本地开发环境下/api/v发出的请求全部代理到http://test.example.com 上(无法访问别点力),并且且会把路径中的 /api替换为''。说人话就是请求/api/a的时候实际上是请求http://test.example.com/a。W同学在本地开发的时候写完代码觉得美滋滋,没有什么问题,于是一键部署到了test环境,准备收工睡觉。

可惜天不遂人意,ld一个☎️打来:你这代码怎么回事?测试环境404了!

不应该啊?W同学仔细检查了代码,发现并没有什么逻辑问题,但是本地和测试环境行为就是不一致。W同学抓耳挠腮不知道怎么办,此时组内大佬过来扫了一眼便发现问题所在: umi的代理只在dev环境生效--简单来说就是测试环境跨域了。这其实是初学者常踩的坑之一,接下来简单剖析一下原因。

原理分析

同源策略是浏览器用于阻止不同源的网页之间进行不受限制的交互,避免潜在的恶意行为。具体来说就是不让不同域名,不同协议,不同端口之间进行数据交互。umi的proxy代理做的事就是先把请求统一到本地服务器localhost:8000,再由本地开发服务器请求远程资源。但这个方法不适用于测试环境了,故会报错。

解决方案

作为小白W不知如何解决,此时ld给他支了三招:

1. 服务器设置白名单:

简单来说就是服务器那边设置一下HTTP 响应头,带Access-Control-Allow-orgin的就可以访问资源,即大名鼎鼎的CORS。这个就需要后端同学解决了,W同学先把这个放到了一边。

2. node作为中间件

node中有一个cors包,可以灵活处理跨域,我让ai写了一个使用demo,觉得基本要领到了就先放在这:

const express = require('express');
const cors = require('cors');
const app = express();

// 使用默认的 CORS 设置,允许所有来源
app.use(cors());

// 或者,你可以自定义 CORS 配置
app.use(cors({
  origin: 'http://example.com',  // 只允许来自 example.com 的请求
  methods: ['GET', 'POST'],     // 只允许 GET 和 POST 请求
  allowedHeaders: ['Content-Type', 'Authorization']  // 允许的请求头
}));

// 示例路由
app.get('/data', (req, res) => {
  res.json({ message: 'Hello from Node.js!' });
});

app.listen(3000, () => {
  console.log('Server is running on http://localhost:3000');
});

这方法不错,但是W同学比较懒,不想再搬个express到项目中,本质上也是和第一种方法一个道理,于是又放到了一边

3. 前端再配置一个baseURL

这个比较ez,也相对常用,基本思路如下:

  1. .env.test中配置测试环境URL
UMI_BASE_URL=http://testc.example.com
  1. 在二次封装的axios中进行单独配置
import HttpRequest from "./axios";//单独封装📦的axios请求,模仿大佬的写法,非常优雅,下一篇讲

const baseURL = process.env.UMI_BASE_URL;

const request = new HttpRequest(baseURL);

export default request;

之后就可以在其他地方发出请求了,不会再出现跨域问题😼。

总结

虽然是一个很小的技术点,但是跨域展开来讲可以涉及axios封装、配置文件的风格、前后端联调和前端安全🔐,故写一个简单的文章记录本次debug,在面试时可以从上面三点出发回答。

再次申明,第一次在平台写技术文章,必然是存在纰漏的,希望各位能在plq指出不足,也欢迎大家分享自己解决跨域的best practice👏。