前后端分离,解决vue+axios跨域和proxyTable不生效等问题

看到我这篇文章前可能你以前看过很多类似的文章。至少我是这样的,因为一直没有很好的解决问题。

正文

当我们通过webstorm等IDE开发工具启动项目的时候,通过命令控制台可以观察到启动项目的命令

如下:

cmd 复制代码
webpack-dev-server --inline --progress --config build/webpack.dev.conf.js

我们很容易发现,用到了一个配置文件build/webpack.dev.conf.js

我因为实在逼得找不到原因,明明按照网上的文章配置的,但是跨域依旧没解决,总会遇到各种各样的问题。

不得已之下,看了下项目的启动配置文件。看完后,感觉自己搞懂了怎么回事,有感。

开始

首先我们要确认后端的跨域是允许的。

首先确保后端跨域没问题,目的是解决前端的问题

Springboot为例可以通过下面注解允许某个接口(注解方法上与@RequestMapping,@GetMapping等相关注解一起使用),或一批接口(注解在类上)

sql 复制代码
@CrossOrigin(originPatterns = "*", allowCredentials = "true", origins = "*")

如果是springsecurity 登录接口,简单代码片段列举,通过csrf().disable() 去允许接口可以跨域

java 复制代码
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()

随着版本的迭代有些配置可能会变更,我们可以通过观看源码找到那些内容发生了变更,然后自己尝试去解决问题。

在网上你会看到各种各样的文章,有人说是改config/vue.config.js,也有人说是改config/index.js 去解决跨域问题。

以我这里为例子,会发现项目中没有vue.config.js与网上某些文章不一样。

通过观看build/webpack.dev.conf.js 源码

截取部分源码,会发现require('../config')引入了config/index.js

最主要的是我们看到了源码中有config.dev.host等相关的内容,

其中我们发现代理相关的词proxy: config.dev.proxyTable, 从这里我们就可以知道用的是proxyTable的配置来代理后端解决跨域问题。

如果你发现项目用的名称不叫 proxyTable 只需要找到对应位置去修改就行了

js 复制代码
'use strict'
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const path = require('path')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')

const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT)

const devWebpackConfig = merge(baseWebpackConfig, {
  module: {
    rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
  },
  // cheap-module-eval-source-map is faster for development
  devtool: config.dev.devtool,

  // these devServer options should be customized in /config/index.js
  devServer: {
    clientLogLevel: 'warning',
    historyApiFallback: {
      rewrites: [
        { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
      ],
    },
    hot: true,
    contentBase: false, // since we use CopyWebpackPlugin.
    compress: true,
    host: HOST || config.dev.host,
    port: PORT || config.dev.port,
    open: config.dev.autoOpenBrowser,
    overlay: config.dev.errorOverlay
      ? { warnings: false, errors: true }
      : false,
    publicPath: config.dev.assetsPublicPath,
    proxy: config.dev.proxyTable,
    quiet: true, // necessary for FriendlyErrorsPlugin
    watchOptions: {
      poll: config.dev.poll,
    }
  },

我们确定了需要改的内容是config/index.js 中的 config.dev.proxyTable 字段配置

js 复制代码
proxyTable: {
  '/api': {
    target: 'http://localhost:8081', // 你请求的第三方接口,后端地址
    changeOrigin: true,// 在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题
    ws: true,
    pathRewrite: { // 路径重写,
      '^/api': ''// 替换target中的请求地址
    }
  }
}

UI 的端口是8080,后台的端口是8081

我们希望用axios去访问8081返回我们想要的数据。

上面的配置意思是,会将 url 以/api 开头通过axios发送的请求会被拦截和代理。

例如我想访问后端的登录接口http://localhost:8081/user/login 去登录返回 token 和user的信息

一般我们会这样做

js 复制代码
axios.post(
	'/user/login', 
	this.loginForm, 
	{headers: {'Content-Type': 'application/x-www-form-urlencoded'}})
.then(res => {
  // TODO
})

如果代理没生效 ,那么它发的请求就是http://localhost:8080/user/login 不是我们期望的8081端口。

实际上代理生效后 ,通过浏览器的Network也看不出来访问的是8081的还是8080端口的。

你只能在Network中看到,request header是8080端口。

因此很多人搞不清。

通过后端打断点,我确认了该请求是否访问到后端api。


上述给的例子中是否有发现proxyTable/api以及内部的pathRewrite配置,

但是我的axios请求中没有/api前缀,因此上述实际proxyTable并没有用,还需要给url带上/api前缀才可以代理生效

修改main.js加入下面片段,将前缀/api 通过总入口方式带入即可。(这样url就不要自己手动拼上/api

js 复制代码
import axios from 'axios'
Vue.prototype.$axios = axios
axios.defaults.baseURL = '/api'
Vue.config.productionTip = false

最后重启vue项目检验一下。

Header信息如下,8080是前端的端口,Request URL: http://localhost:8080/api/user/login这里只是显示成前端的8080,实际上调用的是8081后端的api http://localhost:8081/user/login 后端的springboot接口是@PostMapping("/user/login")

我们可以明显看到后端有返回json数据过来。

相关推荐
star010-36 分钟前
一文学会HTML编程之视频+图文详解详析
前端·网络·网络安全·html·html5
star010-42 分钟前
【视频+图文详解】HTML基础3-html常用标签
前端·css·网络安全·html·html5·学习方法
无限大.6 小时前
前端知识速记:节流与防抖
前端
十八朵郁金香6 小时前
【VUE案例练习】前端vue2+element-ui,后端nodo+express实现‘‘文件上传/删除‘‘功能
前端·javascript·vue.js
学问小小谢6 小时前
第26节课:内容安全策略(CSP)—构建安全网页的防御盾
运维·服务器·前端·网络·学习·安全
LCG元7 小时前
Vue.js组件开发-实现全屏图片文字缩放切换特效
前端·javascript·vue.js
还是鼠鼠8 小时前
图书管理系统 Axios 源码__新增图书
前端·javascript·vscode·ajax·前端框架·node.js·bootstrap
customer088 小时前
【开源免费】基于SpringBoot+Vue.JS体育馆管理系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
还是鼠鼠11 小时前
图书管理系统 Axios 源码 __删除图书功能
前端·javascript·vscode·ajax·前端框架·node.js·bootstrap
轻口味11 小时前
Vue.js `Suspense` 和异步组件加载
前端·javascript·vue.js