记一次vue跨域的解决


Posted in Javascript onOctober 21, 2020

好久不见,今天想写的是前段时间碰到的一个小问题。其实故事背景是前端的同学跟我说他们前端请求不了我后端的数据,说是跨域了。

其实跨域的问题,在如今前后端的时代非常常见,如果图方便的话,一般是在后端的请求以及拦截器中设置header,但是有一些业务需求单纯后端是解决不了的。还是需要前端自行来处理,这次碰到的就是前端需要自行处理的情况。

这里我不细说跨域的解决方案,只聊聊我是怎么解决的。如果大家想要知道更详细的跨域知识,可以点个在看!我下次写一个专题。

vue跨域代理解决方案

记一次vue跨域的解决

其实需求比较简单,就是先post模拟登陆到B服务器,然后get请求B服务器上指定接口的数据,返回给A服务器。

当然这里的A服务器目前是处于我本机电脑。

首先,我们需要在根目录下配置vue.config.js,这个文件不是每个项目都有的,如果没有的可以自行配置。根据vue官网的说法,这个文件是可选配置,如果项目的 (和 package.json 同级的) 根目录中存在这个文件,那么它会被 @vue/cli-service 自动加载。

这个文件里面具体配置有什么,这里给大家官网的地址:

https://cli.vuejs.org/zh/config

官网中详细介绍了每一个参数的配置,当然我们需要什么就可以拿什么参数来配置。这里我从网上找了一份比较全面的vue.config.js,大家直接复制粘贴即可

// vue.config.js 配置说明
//官方vue.config.js 参考文档 https://cli.vuejs.org/zh/config/#css-loaderoptions
// 这里只列一部分,具体配置参考文档
module.exports = {
// 部署生产环境和开发环境下的URL。
// 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上
//例如 https://www.my-app.com/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.my-app.com/my-app/,则设置 baseUrl 为 /my-app/。
//baseUrl 从 Vue CLI 3.3 起已弃用,请使用publicPath
//baseUrl: process.env.NODE_ENV === "production" ? "./" : "/",
publicPath: process.env.NODE_ENV === "production" ? "./" : "/",

// outputDir: 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)
outputDir: "mycli3",
//用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
assetsDir: "assets",
//指定生成的 index.html 的输出路径 (打包之后,改变系统默认的index.html的文件名)
// indexPath: "myIndex.html",
//默认情况下,生成的静态资源在它们的文件名中包含了 hash 以便更好的控制缓存。你可以通过将这个选项设为 false 来关闭文件名哈希。(false的时候就是让原来的文件名不改变)
filenameHashing: false,

//  lintOnSave:{ type:Boolean default:true } 问你是否使用eslint
lintOnSave: true,
//如果你想要在生产构建时禁用 eslint-loader,你可以用如下配置
// lintOnSave: process.env.NODE_ENV !== 'production',

//是否使用包含运行时编译器的 Vue 构建版本。设置为 true 后你就可以在 Vue 组件中使用 template 选项了,但是这会让你的应用额外增加 10kb 左右。(默认false)
// runtimeCompiler: false,

/**
 * 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
 * 打包之后发现map文件过大,项目文件体积很大,设置为false就可以不输出map文件
 * map文件的作用在于:项目打包后,代码都是经过压缩加密的,如果运行时报错,输出的错误信息无法准确得知是哪里的代码报错。
 * 有了map就可以像未加密的代码一样,准确的输出是哪一行哪一列有错。
 * */
productionSourceMap: false,

// 它支持webPack-dev-server的所有选项
devServer: {
  host: "localhost",
  port: 8081, // 端口号
  https: false, // https:{type:Boolean}
  open: true, //配置自动启动浏览器
  // 配置多个代理
  proxy: {
    "/apis": {
      target: "http://xxx.xx.xx.xx:xxxxx",// 要访问的接口域名
      ws: true,// 是否启用websockets
      changeOrigin: true, //开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题
      pathRewrite: {
        '^/apis': '' //这里理解成用'/api'代替target里面的地址,比如我要调用'http://40.00.100.100:3002/user/add',直接写'/api/user/add'即可
      }
    }
  }
}
};

当然,我们可能不需要这么多的配置,这里我们主要来看这段代码:

devServer: {
   host: "localhost",
   port: 8081, // 端口号
   https: false, // https:{type:Boolean}
   open: true, //配置自动启动浏览器
   // 配置多个代理
   proxy: {
     "/apis": {
       target: "http://xxx.xx.xx.xx:xxxxx",// 要访问的接口域名
       ws: true,// 是否启用websockets
       changeOrigin: true, //开启跨域
       pathRewrite: {
         '^/apis': '' //这里理解成用'/api'代替target里面的地址,比如我要调用'http://40.00.100.100:3002/user/add',直接写'/api/user/add'即可
       }
     }

这个地方就是配置代理的地方,如果你是使用webpack模板来构建的vue项目,这个配置文件是config/index.js,其实功能类似。

在proxy字段中target就是我们要跨域的url,pathRewrite中的^/apis,就是来替代target中你所填写的url,什么意思呢?可以继续看下面。

this.$axios({
  method: "POST",
  url: `/apis/login`,
  headers: {
   'Content-Type': 'application/x-www-form-urlencoded'
  },

  data: {
       "email": "xxxxxxx",
       "password": "xxxxxxx",
       "remember": "on"
      },
  withCredentials: true,

 })

在上面的url中你看到我写的是/apis/login,但是实际上请求的是http://xxx.xx.xx.xx:xxxxx/login。也就是说apis将target中的url代替了,这样就能够让vue知道你这里需要用到代理的方式。

其实到了这里跨域的问题已经解决了,你再次请求的时候会发现没有报跨域的错误。

但是,又会有一些新的错误,可能你不会遇到但很有可能也会遇到,这个跟后端接受数据的格式有关。

将axios中的表单数据转为form-data形式

如果你不是form-data的形式,你可能会遇到400的错误,400错误按照网上的说法是你的content-type没设置对,但这只是一方面,另一方面是你所传递的data不一定跟后端相契合。

这里你可能需要通过axios设置拦截器来解决这个问题:

在你的main.js中,设置如下:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './api'
import axios from 'axios'
import qs from 'qs'


Vue.config.productionTip = false
Vue.prototype.$axios = axios

axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
axios.defaults.headers.post["Access-Control-Allow-Origin"] = "*";
// 设置拦截器
axios.interceptors.request.use(
  config => {
   if (config.method === 'post') {
    config.data = qs.stringify(config.data);
   }
   return config;
  },
  error =>{
   return Promise.reject(error);
  }
);

new Vue({
 router,
 store,
 render: h => h(App)
}).$mount('#app')

总结

这篇文章对于跨域写得并不是很全面,但是对于这方面有困惑的同学,我相信看了之后会茅塞顿开。跨域问题的思考思路无非就是前端和后端两方面。分别简单测试一下就能够锁定问题出在哪方面。如果你觉得这篇文章对你现在或者以后有用,麻烦给个在看支持吧!

以上就是记一次vue跨域的解决的详细内容,更多关于vue 跨域的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
js 替换功能函数,用正则表达式解决,js的全部替换
Dec 08 Javascript
JS鼠标事件大全 推荐收藏
Nov 01 Javascript
Script标签与访问HTML页面详解
Jan 10 Javascript
js或jquery实现页面打印可局部打印
Mar 27 Javascript
JavaScript中的6种运算符总结
Oct 16 Javascript
JavaScript数组随机排列实现随机洗牌功能
Mar 19 Javascript
深入浅析javascript中的作用域(推荐)
Jul 19 Javascript
js实现的页面加载完毕之前loading提示效果完整示例【附demo源码下载】
Aug 02 Javascript
Vue.js每天必学之构造器与生命周期
Sep 05 Javascript
JavaScript奇技淫巧44招【实用】
Dec 11 Javascript
Vue.js系列之vue-router(上)(3)
Jan 03 Javascript
jQuery实现经典的网页3D轮播图封装功能【附源码下载】
Feb 15 jQuery
解决Vue项目中tff报错的问题
Oct 21 #Javascript
vue-cli3自动消除console.log()的调试信息方式
Oct 21 #Javascript
js 压缩图片的示例(只缩小体积,不更改图片尺寸)
Oct 21 #Javascript
vue-cli4使用全局less文件中的变量配置操作
Oct 21 #Javascript
Vue全局使用less样式,组件使用全局样式文件中定义的变量操作
Oct 21 #Javascript
js 图片懒加载的实现
Oct 21 #Javascript
uniapp实现可以左右滑动导航栏
Oct 21 #Javascript
You might like
CodeIgniter删除和设置Cookie的方法
2015/04/07 PHP
PHP创建文件及写入数据(覆盖写入,追加写入)的方法详解
2019/02/15 PHP
Laravel 自定命令以及生成文件的例子
2019/10/23 PHP
25个非常棒的jQuery滑块插件和教程小结
2011/09/02 Javascript
javascript学习笔记(二)数组和对象部分
2014/09/30 Javascript
jQuery DataTables插件自定义Ajax分页实例解析
2020/04/28 Javascript
原生JS京东轮播图代码
2017/03/22 Javascript
微信小程序之GET请求的实例详解
2017/09/29 Javascript
Angular浏览器插件Batarang介绍及使用
2018/02/07 Javascript
angular5 子组件监听父组件传入值的变化方法
2018/09/30 Javascript
javascript使用链接跨域下载图片
2019/11/01 Javascript
微信小程序复选框实现多选一功能过程解析
2020/02/14 Javascript
python根据文件大小打log日志
2014/10/09 Python
python计算时间差的方法
2015/05/20 Python
详解字典树Trie结构及其Python代码实现
2016/06/03 Python
Android 兼容性问题:java.lang.UnsupportedOperationException解决办法
2017/03/19 Python
使用Python生成XML的方法实例
2017/03/21 Python
浅谈python中的占位符
2017/11/09 Python
Python装饰器(decorator)定义与用法详解
2018/02/09 Python
python matplotlib绘图,修改坐标轴刻度为文字的实例
2018/05/25 Python
python矩阵转换为一维数组的实例
2018/06/05 Python
浅谈python的dataframe与series的创建方法
2018/11/12 Python
python 杀死自身进程的实现方法
2019/07/01 Python
python opencv实现图像配准与比较
2021/02/09 Python
pip/anaconda修改镜像源,加快python模块安装速度的操作
2021/03/04 Python
详解HTML5 data-* 自定义属性
2018/01/24 HTML / CSS
新西兰最大的连锁超市:Countdown
2020/06/04 全球购物
Servlet面试题库
2015/07/18 面试题
工程专业求职自荐书范文
2014/02/08 职场文书
逃课检讨书
2015/01/26 职场文书
世界红十字日活动总结
2015/02/10 职场文书
小学国庆节活动总结
2015/03/23 职场文书
2016小学优秀教师先进事迹材料
2016/02/26 职场文书
使用numpy实现矩阵的翻转(flip)与旋转
2021/06/03 Python
SQLServer之常用函数总结详解
2021/08/30 SQL Server
vmware虚拟机打不开vmx文件怎么办 ?vmware虚拟机vmx文件打开方法
2022/04/08 数码科技