在Web开发的时候会遇见一个常见的问题,跨域问题,这也是前后端分离的场景常见的问题,下面来看看这个东西是啥,如何应用的吧?
技术派中的跨域问题,有两处,一处是加载CDN图片时;一处是admin端请求后端API接口时。
来看看跨域问题的解决思路和发生原因吧。
什么是跨域问题
跨越对于前后端开发者来说,像一块狗皮膏药,无论是面试还是开发中,都会经常遇到。
之所以出现跨域问题,是因为浏览器的同源策略,为了隔离潜在的恶意文件,为了防御五花八门的攻击,浏览器限制了从同一个源加载的文档或者脚本与来自另一个源的资源进行交互。
同源策略要求,如果两个网页的协议、域名和端口都相同,他们才会认为是同源,否则就是跨域。
同源策略是浏览器为了保护用户信息安全而实施的一种安全机制,可以防止恶意网站通过脚本窃取用户在其他网站上的数据,或者伪造用户身份执行一些操作。
现在有一个Web应用,运行在5174端口下,它有一个login请求,请求的是8080端口,那么就会出现跨域问题。
演示一下?
1.运行技术派,以便提供后端服务。技术派默认是运行在8080端口下的。
2.安装Node.js,是一个基于ChromeV8 JavaScript引擎的开源、跨平台的运行时环境,它允许在服务器端运行JavaScript代码。在它出现之前,JavaScript京仅仅支持浏览器端,用于处理客户端逻辑与用户互动,它的出现极大的扩展了JavaScript的使用范围,使其成为了以哦个全站的开发语言。
3.通过命令创建一个新的Vite + React应用。
进入my-app目录:
安装依赖:
在Src的目录下面编辑如下内容:
import { useState } from 'react';
import reactLogo from './assets/react.svg';
import viteLogo from '/vite.svg';
import './App.css';function App() {const [response, setResponse] = useState<string>('');const handleLogin = async () => {try {const res = await fetch('http://localhost:8080/api/admin/login', {method: 'POST',headers: {'Content-Type': 'application/json',},body: JSON.stringify({username: 'your-username',password: 'your-password',}),});const data = await res.json();setResponse(JSON.stringify(data));} catch (error) {console.error('Error:', error);setResponse('An error occurred');}};return (<div><button onClick={handleLogin}>Login</button><p>{response}</p></div>);
}export default App;
运行Vite,Vite(快)是一个现代化的、轻量级的、基于浏览器的原生ES模块开发工具,Vite由Vue.js创始人尤雨溪开发,旨在为前端带来更快的构建速度和更高的开发效率。:
此时,在浏览器中访问 http://localhost:5174/ 你将在控制台看到跨域的错误,因为前端应用(在5174端口)正在尝试访问非同源的后端服务(在8080端口)。这个就时带典型的跨域问题。
如何让解决跨越问题呢?
理解啦跨越问题的发生原因,解决就显而易见了。
我们可以使用Node.js代理来解决跨域问题,思路即是,在本地创建一个虚拟的服务器,对5174端口下面的前端请求进行代理,同时接受8080端口下的服务端响应,这样服务端和服务端进行数据交互就不会出现跨域问题了。
在vite.config的server配置中
添加代理配置。
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'// https://vitejs.dev/config/
export default defineConfig({plugins: [react()],server: {proxy: {"/admin": {target: "http://127.0.0.1:8080/",changeOrigin: true,rewrite: path => path.replace(/^\/api/, ""),},},},
})
他将所有以/admin开头的请求转发到 http://127.0.0.1:8080/
- proxy: 一个包含代理规则的对象。
- /admin: 指定要代理的路径前缀。所有以/admin开头
- target: 目标服务器的URL,所有匹配的请求将会被转发到此URL
- changeOrigin: 设置为true时,代理会修改请求头中的Host,使其与目标服务器一致。
有助于避免某些服务器对Host头进行验证情况。
rewrite:一个函数,用于重写请求路径。在这个例子中,他会移除路径中的/api部分。例如,一个请求路径为/admin/some-endpoint的请求将会被代理到http://127.0.0.1.8080/some-endpoint。
运行技术派的admin端
简单总结一下,通过同源服务器上设置代理(Nginx,Node.js),将请求转发到服务器上,这样客户端和代理服务器之间就可以满足同源策略,而代理服务器与目标服务器之间的通信就不再收到同源策略的限制,做法很简单。