从壹开始前后端分离 [.netCore 填坑 ] 三十三║ ⅖ 种方法实现完美跨域
缘起
哈喽大家周四好,趁着大家在团建的时候花一个下午学点儿东西,也是督促大家学习哟,希望大家看到老张的文章,可以有一丢丢的学习动力。不过话说过来,该吃的团建还是要去的,不能学我呀 [ /(ㄒoㄒ)/~~ ],昨天开始搭建公司的前后端分离项目,纠结是 Iview 还是 ElementUI ,百思不得其解,都说处女座纠结,我一个巨蟹为何如此,欢迎大佬们给出意见和建议~~~
开发 Vue 的时候,哪一种前端样式框架更好?
鉴于群里小伙伴问得最多的问题,这里找到Top3的其中之一,就是跨域问题(下次说说EFCore),当然这个问题是老生常谈的问题了,而且在之前的时候也已经说过了,不知道大家在使用的时候怎么样——坑来自于文章《框架之十二 || 三种跨域方式比较》。当然,大家会问了,既然都说过了,为何还要说呢,特别是使用 CORS 来实现跨域,很轻松,短短的几行代码就搞定了,但是或多或少会遇到这样的问题,1、把Http和 Https 搞混了,失败;2、如果是前端端口号不固定,会经常要后端配置端口号,麻烦;3、最重要的一点就是把我们的接口地址暴漏出去了,不爽;如果你不信,可以看看我之前自己的一个线上版本 http://vue.blog.azlinli.com/#/,
虽然接口数据很正常被获取,但是接口地址还是不想暴露出去,欸?!那咋办,这就是说到了今天说的内容了,大家看我写的标题应该也能明白,⅖ 种方法—— 前边的三种方法已经说了,这里再重温下:
0、不跨域 —— 前后端写在一起,别笑,还真的有人已经把Vue 和 .net 整合到一起了,不说明
1、JsonP —— 在JQ中挺好,弊端也有,浅尝辄止
2、添加请求头 —— 需要后端来设计,不推荐
3、CORS —— 这个是我在跨域中遇到的神器,优缺点上边也说了,还是很不错的,推荐使用
4、webpack 本地代理 —— dev 环境的一大神器,只需在 webpack 中三行配置,即可代理到本地,只能在本地,大弊端,不过仍推荐使用
5、Nginx 反向代理 —— 完美解决 Build 后生产环境中的跨域问题,配合以后的负载均衡,强烈推荐
因为前三种跨域方法,已经在之前的文章中提到了《框架之十二 || 三种跨域方式比较》 ,这里就不多说了,今天主要说说 Webpack 的本地代理,和Nginx反向代理实现跨域,完全不用对后端进行操作;
最终我们的 博客项目一 的呈现的效果 http://vueblog.neters.club/:发现以及成功代理到本地了,并且是发布到服务器版本
一、基于webpack 的 proxy 代理——开发环境很方便
1、Vue-Cli 3.0 新增全局配置文件 vue.config.js
vue项目搭建的时候,会有一个全局config配置文件,在 vue-cli 2.0 脚手架中,很明显的把它放到了 config 的一个文件夹中,是这样的,我们在 index.js 中可以端口号的配置,打包之后路径的配置,图片的配置 等等
但是 vue-cli 3.0 脚手架中,去掉了 config 这个文件夹,那我们如何配置呢,我们可以在项目根目录新建一个 vue.config.js 文件,像之前的很多繁琐配置,都可以在这个文件里配置啦。官方说明,vue.config.js 是一个可选的配置文件,如果项目的 (和 package.json 同级的) 根目录中存在这个文件,那么它会被 @vue/cli-service 自动加载。你也可以使用 package.json 中的 vue 字段,但是注意这种写法需要你严格遵照 JSON 的格式来写。
我们就在根目录下新建该文件,然后添加内容:
module.exports = { // 基本路径 baseUrl: "/", // 输出文件目录 outputDir: "dist", // eslint-loader 是否在保存的时候检查 lintOnSave: true, // webpack配置 // see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md chainWebpack: () => {}, configureWebpack: () => {}, // 生产环境是否生成 sourceMap 文件 productionSourceMap: true, // css相关配置 css: { // 是否使用css分离插件 ExtractTextPlugin extract: true, // 开启 CSS source maps? sourceMap: false, // css预设器配置项 loaderOptions: {}, // 启用 CSS modules for all css / pre-processor files. modules: false }, // use thread-loader for babel & TS in production build // enabled by default if the machine has more than 1 cores parallel: require("os").cpus().length > 1, // PWA 插件相关配置 // see https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa pwa: {}, // webpack-dev-server 相关配置 devServer: { open: true, //配置自动启动浏览器 host: "127.0.0.1",//主机 port: 6688, // 端口号自定义 https: false,//是否开启https安全协议 hotOnly: false, // https:{type:Boolean} proxy: null, // 设置代理 before: app => {} }, // 第三方插件配置 pluginOptions: { // ... } };
相应的注释都有,主要是配置 devServer ,从名字上也能看出来,这个是 dev 开发环境的服务配置,常用来配置我们的端口号 port ,还有一个就是 proxy 的设置代理。
2、配置 proxy 本地代理
将上边的 proxy: null 注释掉,然后修改代理设置:
proxy: { // 配置多个代理 "/api": {//定义代理名称 target: "http://123.206.33.109:8081",//我们的接口域名地址 ws: true, changeOrigin: true,//允许跨域 pathRewrite: { // 路径重写, "^/apb": "" // 替换target中的请求地址,(这里无效,但是可以自定义处理) } } },
这样,我们就把接口地址代理到了本地,那代理到本地,如何调用呢,请往下看。
3、修改接口api地址,http.js文件
还记得我们在 src 文件夹下有一个 api/http.js 文件么,这个就是配置我们的 http 请求相关的,其他的都不变,我们只需要把域名去掉即可,或者写上本项目的域名:
// 配置API接口地址 var root1 = "http://localhost:58427/api";//没有代理的本地api地址 var root2 = "http://123.206.33.109:8081/api/";//没有代理的服务器api地址 var root = "/api/";//配置 proxy 代理的api地址,也可以写成http://localhost:6688/api
其实说白了,就是在项目启动的时候,在node服务器中,是把所有的 /abi == http://localhost:6688/api 的都指向了 http://123.206.33.109:8081 域名,这样就实现了跨域
其他任何都不需要变,接口的使用还是原来的使用方法,这样,我们在本地开发的时候,就可以获取到后端api数据了,不用再去 .net core 中设置跨域CORS了,是不是很方便。
4、本地浏览效果
记得我们修改 vue.config.js 后要重启下服务,然后就可以看到项目成功获取数据,并代理到本地:
可以看到,我们已经把远程接口数据 123.206.33.109 成功的代理到了本地 localhost:6688 ,是不是很简单!
5、build 打包发布 IIS
那我们本地开发好了,是不是一切都稳妥了呢,我们可以试一试,通过 build 打包,生成 dist 文件夹,然后将文件夹拷贝到服务器,并配置 IIS ,这个很简单,就和配置普通静态页面是一样的,
我们发现虽然页面可以浏览(可以渲染,证明我们的 vue 已经生效),但是却获取不到数据,这证明我们上边的 proxy 代理,只是适用本地dev开发环境中:
截图
虽然这个本地代理的方法很简单,特别适合我们独立开发,在跨域这一块,完全不用和后端做处理,但是如何解决发布状态的呢,请继续往下看。
二、基于Nginx 的反向代理——打包发布一键搞定
这篇文章仅仅是如何使用 Nginx 作为一个反向代理服务器,具体的深入原理以及负载均衡器等等,我会在以后的微服务系列中说到(不知不觉又给自己玩了一个坑😭)。
1、Nginx的代理工作原理
反向代理(Reverse Proxy)方式是指以代理服务器来接受 Internet上 的连接请求,然后将请求转发给内部网络上的服务器;并将从服务器上得到的结果返回给 Internet 上请求连接的客户端,此时代理服务器对外就表现为一个服务器。
通常的代理服务器,只用于代理内部网络对 Internet 外部网络的连接请求,客户机必须指定代理服务器,并将本来要直接发送到 Web 服务器上的 http 请求发送到代理服务器中。不支持外部网络对内部网络的连接请求,因为内部网络对外部网络是不可见的。当一个代理服务器能够代理外部网络上的主机, 访问内部网络时,这种代理服务的方式称为反向代理服务。此时代理服务器对外就表现为一个Web服务器,外部网络就可以简单把它当作一个标准的 Web 服务器 而不需要特定的配置。不同之处在于,这个服务器没有保存任何网页的真实数据,所有的静态网页或者CGI程序,都保存在内部的Web服务器上。因此对反向代 理服务器的攻击并不会使得网页信息遭到破坏,这样就增强了Web服务器的安全性。
总结来说呢,就是我们通过 nginx 反向代理服务器处理我们的请求,具体的数据处理还是交给 IIS,然后得到处理过的数据以后,我们再发送给 Internet 请求的客户端,这样就不会存在跨域的问题了。
2、Nginx 下载与使用
下载地址:http://nginx.org/en/download.html
我选择下载稳定版 1.14 ,下载好后解压,然后就看到根目录下的 Nginx.exe ,直接双击即可开启服务,然后就会在任务管理器查看到已经启动的 Nginx 代理服务。
因为默认的是80端口,大家的端口应该都已经被占用,所以我们需要修改端口
打开 config 文件夹下的 nginx.conf 文件,然后修改端口号
server { listen 8077; server_name localhost;
这个很简单,这个时候记得要重启 Nginx 服务,你可以采用命令的形式,不过我有时候会发现无效,我一般使用的时候,在任务管理器中把所有的 nginx 进程全部结束,然后双击 nginx.exe 开启。
这个时候我们直接访问 localhost:8077 就发现已经启动成功了,只不过是 nginx 的欢迎页。
老张说:这个时候你一定好奇,为什么仅仅配置下,就能访问该端口呢,不信的话,你可以在 cmd 中 通过 netstat -an 命令来查看 8077 端口是否被使用
发现已经被监听使用,如果还不相信,你可以创建一个 IIS 项目,然后配置 8077 端口,发现会报错,这也就是说明了,8077端口已经被占用,准确来说是被 Nginx 占用的,所以,Nginx 和 IIS一样都是可以作为反向代理服务器来使用,从而可以通过监听端口来代理我们的项目的:
3、将上文打包后的 dist 文件,配置 Nginx 代理
1、将我们上边 build 后的 dist 文件,放到咱们下载的 nginx 下的 html文件夹
2、配置代理
还是我们的 config/nginx.conf 文件,打开并配置 本地代理 ,注意注释是用 # 号,不是 //
server { listen 8077;#监听端口,也就是我们的项目端口 server_name localhost;#服务器主机 location / { root html;#监听文件夹,默认是nginx下的html文件夹,也可以自定义物理路径 E:\\Nginx\\test index index.html index.htm;#默认首次启动的文件 } #配置本地代理规则 location /api {#名字取一个 api rewrite ^.+apb/?(.*)$ /$1 break; #路径重写机制(无用,但是你也可以自己定义,对路由进行变化) include uwsgi_params; proxy_pass http://123.206.33.109:8081; #api接口的域名地址 }
4、本地以及服务器发布预览
这个时候,你再访问 localhost:8077 就能看到我们的项目内容了,访问页面也能看到我们的数据了,代理成功!
这个时候仅仅是本地,那服务器行不行呢,我们只需要将我们的 nginx 文件夹拷贝到服务器,并且双击 nginx.exe 启动代理服务,然后就可以啦!
是不是很简单,只需要把http.js 的baseurl 修改一下,完全不用修改我们任何的调用接口地址,也不用修改后端,就可以实现跨域。
相关代理,包括 nginx 文件夹,我已经放到 git 上,大家可以自己看一看。
5、刷新后出现 404
如果使用Ngxin 部署,可能会出现刷新的时候,404 的问题,有复杂的,也有简单的办法,复杂的以后补充,这里先说下简单的:
就是直接在 dist 中,复制 index.html ,然后重命名一个新文件 404.html ,这两个文件是一模一样的:
三、结语
本篇文章是接着上一篇跨域文章的下篇,通过这 5 种方法,很好的实现了跨域问题,不仅仅是在 Vue 项目中,其他任何都可以这么使用,完美的解决了问题,与 CORS 相比,Nginx 更有前端主动权,各有利弊,我更倾向于 Nginx 代理,因为以后会涉及到负载均衡的使用,好啦,明天说说 EFCore 的使用吧(注:这是我的一个坑,本来想写一篇文章,但是发现比较简单,大家看看官网就知道,或者看我的第二个DDD系列中,用到了这个EFCore,如果想了解,可以直接看源代码和相关文章,很简单的都是https://github.com/anjoy8/ChristDDD)。
四、Github
https://github.com/anjoy8/Blog.Vue