导读:主要解决在开发环境中 域名或者IP地址与后端给的接口不一致导致的CORS问题
在开发环境中避免CORS
今天,我们选择用于前端开发的大多数开发服务器都使用Nodejs。这些Node服务器中的大多数都支持代理配置。此外,Angular,react和vue附带了webpack开发服务器,该服务器内置了对代理配置的支持。
那么这个代理配置到底是做什么的呢?
假设你的前端应用程序在 http://localhost:8080 中运行,而后端API在http://172.28.128.207:8610/sysUser/login 中运行。我们的前台需要存储后端API的URL和端口,以便在本地运行应用程序。为了支持这一点,你还需要在你的后端API中启用CORS,允许从运行在 http://locahost:8080 的前端服务器上访问。
通过在前端开发服务器中使用代理配置,我们可以避免上述所有麻烦。使用代理时,只需在前端应用程序中存储相对路径(/api):
在man.js 中添加:
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import Antd from 'ant-design-vue';
import { message } from 'ant-design-vue'
import axios from 'axios'
import './assets/main.css'
import 'ant-design-vue/dist/antd.css';
const app = createApp(App)
app.use(globalPinia)
// import.meta.env.DEV 返回是否為開發環境的布爾值
axios.defaults.baseURL = import.meta.env.DEV ? "/api" : "/"
// 僅在開發環境的時候, 在URL前面添加 /api
//this.$axios.post('(在此處自动添加/api)/sysUser/login', form)
//实际效果为'/api/sysUser/login'
axios.interceptors.response.use(res => {
if (res["status"] === 200) {
// const data = res["data"]
// switch (data["status"]) {
// case "200": return Promise.resolve(data["data"])
// case "404": return Promise.reject(data["message"])
// case "500": return Promise.reject(data["message"])
// default: return Promise.reject("Axios 異常, 無法找到匹配項 (" + data["status"] + ")")
// }
if (res["data"]["status"] == 401) {
message.error("登錄狀態已失效, 請重新登錄")
router.replace({ name: "Login", query: { "action": "clear" } })
return Promise.reject("登錄狀態已失效, 請重新登錄")
} else {
return Promise.resolve(res["data"])
}
} else if (res["status"] === 404) {
message.error("接口不存在, 請聯繫網站管理員")
return Promise.reject(err)
} else if (res["status"] === 500) {
message.error("服務器錯誤, 請聯繫網站管理員")
return Promise.reject(err)
}
return res
}, err => {
message.error("網絡請求錯誤, 請稍後重試, 如果再次發生請聯繫網站管理員")
console.error(err)
return Promise.reject(err)
})
axios.interceptors.request.use(config => {
config.headers["Authorization"] = userInfoStore.authorization
return config
})
app.config.globalProperties.$axios = axios //把配置好的axios挂载到app的全局axios 上
app.use(router)
app.use(Antd)
app.mount('#app') //app挂载app实例上.
在本地运行应用程序时,你的前端依旧使用相同的域和端口(http://localhost:8080/sysUser/login)访问后端API,浏览器无需担心CORS。
在此阶段,前端服务器代理会尽力而为。在代理配置内部,你可以定义将在前端开发服务器上针对路径 /api 的所有请求转发到http://172.28.128.207:8610。
在vite.config.js中配置:
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
//vite 前端server配置
server: {
proxy: {
// 如果 url 中以 /api 开头, 則前端server与后端server对接,略过web,
//將請求轉發至 target 目标地址, 效果相當於 http://172.28.128.207:8610/api/sysUser/login
'/api': {
target: 'http://172.28.128.207:8610/', // 代理的目标地址
changeOrigin: true, // 开发模式,默认的origin是真实的 origin:localhost:8080
// 代理服务会把origin修改为目标地址
// secure: true, // 是否https接口
// ws: true, // 是否代理websockets
rewrite: (path) => path.replace('/api', '') // 路径重写
} // 將 url中的 /api 替換成 ''
} //http://172.28.128.207:8610/api/sysUser/login
}, //变成http://172.28.128.207:8610/sysUser/login 才能正常访问
})
由于开发服务器是与后端API通信的中间人,因此可以安全地避免CORS。下面的示例显示了如何在webpack开发服务器中添加代理配置:
module.exports = {
//...
devServer: {
proxy: {
'/api': 'http://localhost:3000'
}
}
};
流程原理源于博客园,修改了内容添加了一些自己的理解