Vue+nginx 实现跨域访问

1、跨域和同源策略

什么是同源策略?           

同源策略是指浏览器处于安全考虑的情况下,只允许本域下的借口进行交互。不同源的客户端在没有授权的情况下是不允许获取对方资源的。

本域指的是什么?

    同协议:例如相同的http或https

    同域名:例如https://baidu.com/aaa 和 https://baidu.com/bbb

  同端口:例如8080端口

一个示例:

跨域解决方案:

    JSONP

    CORS

    nginx反向代理

    降域

    postMessage

 

JSONP:最早的解决方案,利用script标签可以跨域的原理实现,只支持get请求

CORS:同源策略

优势:

    在服务端进行控制是否允许跨域,可自定义规则

    支持各种请求方式

缺点:

    会产生额外的请求

阮一峰对CORS的解析:http://www.ruanyifeng.com/blog/2016/04/cors.html

 

nginx反向代理

思路是:利用nginx反向代理把跨域为不跨域,支持各种请求方式

缺点:需要在nginx进行额外配置,语义不清晰

 

降域和postMessage:

https://www.jianshu.com/p/7666e1ffb8c6

 

当没api接口遇到跨域问题时,会报XMLHttpRequest跨域提示:

 

当使用CORS策略,解决跨域问题时,我的做法是在服务端设置允许访问的接口地址:

app.use(async (ctx, next) => {

    //添加允许请求头

    // ctx.append('Access-Control-Allow-Origin', '*')

    // ctx.append('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild')

    // ctx.append('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS,PATCH')

    // //ctx.append('Content-Type', 'application/json;charset=utf-8')

    // console.log(`Process ${ctx.request.method} ${ctx.request.url}...`);

    // logger.info(`Process ${ctx.request.method} ${ctx.request.url}...`)

    //http 预请求处理(post/put/delete 请求在正式请求之前会先发送一个OPTIONS的预请求,只需要把这个OPTIONS的预请求正常返回,后续的请求就会正常执行)

 

    if (ctx.request.method === 'OPTIONS') {

        ctx.body = "OK"

    } else {

        //继续执行api请求

        await next();

    }

});
node.js设置允许跨域

 

因为项目中使用的是vue+node.js实现,而vue自身可以设置proxy实现跨域,所以最终采用vue proxy+nginx反向代理,实现跨域

 

2、Vue 设置代理实现本地跨域

当前项目使用vue-cli3.0版本构建

首先在根目录下创建vue.config.js文件,这个配置文件会在运行项目的时候自动加载

module.exports = {

    runtimeCompiler: true,

    publicPath: '/', // 设置打包文件相对路径

    devServer: {

        open: process.platform === 'darwin',

        host: '127.0.0.1',

        port: 3000,

        // open: true, //配置自动启动浏览器

        proxy: {

            '/api': {

                // target: process.env.VUE_APP_BASE_URL, //对应自己的接口

                target: 'http://www.xxx.com', //对应自己的接口

                changeOrigin: true,

                ws: true,

                pathRewrite: {

                    '^/api': ''

                }

            }

        }

    },

}
vue.config.js proxy

解释:

proxy对象标识,对/api 开头的接口实现代理

       target:’’,代理的接口地址,

       changeOrigin:true,是否跨域

       secure:false, 如果是https接口,需要配置这个参数

       pathRewrite:{},//重写api路径,因为原来接口中不存在’/api’,我们人为加上去就是为了标识哪些接口需要实现代理,但是真正访问接口的时候还是要把接口uri中的‘/api’替换为‘’

 

我们不仅可以为’/api’实现代理,也可以为其他具有同类功能的接口实现代理,比如我们的接口是发布在多个微服务中的,就需要我们设置多个代理地址,

这时,就不能对axios设置统一的baseURL

//axios.defaults.baseURL = ‘’

 

在使用axios请求接口的时候,如果需要跨域,则在请求接口前加载‘/api’,例如:

const server=’/api’

const uri=server+’/ patient_survey/findByPage’

axios.post(uri).then(res=>{})

 

配置完成之后本地就可以跨域访问了,

通过浏览器F12查看请求地址为:

 

但是实际的接口请求地址为:devServer.proxy.target中的地址

所以实际请求的uri为:http:www.xxx.com/patient_survey/findByPage

 

3、vue+nginx实现服务端跨域

但是把vue项目打包发布之后,调用接口会提示404错误,这时还需要在nginx中做一下反向代理

在服务器中找到nginx的配置文件nginx.config

在需要添加反向代理的配置项中添加如下:

location /api {

                rewrite ^.+api/?(.*)$ /$1 break; //可选参数,正则验证地址

                include uwsgi_params; //可选参数,uwsgi是服务器和服务端应用程序的通信协议,规定了怎么把请求转发给应用程序和返回

                proxy_pass http://www.xxx.com;// 此处修改为自己的请求地址,必填

        }

  server {

        listen 80;

        server_name xxx.com;

        charset utf8;

 

        location / {

                root /data/release/xxx;

                index index.html;

                proxy_pass http://127.0.0.1:8003;

                }

 

             location /api {

                rewrite ^.+api/?(.*)$ /$1 break;

                include uwsgi_params;

                proxy_pass http://www.xxx.com;

        }

 

 

        error_page 404 /404.html;

                location = /40x.html {

        }

        error_page 500 502 503 504 /50x.html;

                location = /50x.html {

        }

}
nginx.config 中的server配置信息

设置完成后 重启nginx

  • nginx –s reload

完成后服务器应该也能实现跨域

参考:

https://www.cnblogs.com/zhaohongcheng/p/11250161.html

 

4、vue配置环境变量

在实现vue的跨域访问之后,为了方便本机调试和发布,可以在vue中设置不同的环境变量,使项目在不同的环境中自动调用不同的接口地址

 

需要文件:

在vue项目根目录下创建三个文件

 .env 无论开发环境还是生成环境都会加载

 .env.development 开发环境加载这个文件

 .env.production 生成环境加载这个文件

如果需要其他环境,可以继续添加其他环境的配置文件

.env 文件内容:

    NODE_ENV = production

.env.development 文件内容:

    NODE_ENV = development

    VUE_APP_BASE_URL = http://localhost:3000/

.env.production 文件内容:

    NODE_ENV = production

    VUE_APP_BASE_URL = http://www.xxx.com/

(其中’VUE_APP_’是固定前缀,不可以更改)

文件加载顺序:

首先加载.env文件,判断当前的项目环境,

如果是开始环境,则继续加载.env.development的内容,

如果是生产环境,则加载.env.production的内容,

ps:测试发现,当前的系统环境并不是.env文件中的NODE_ENV =xxx 确定的,而是根据实际情况决定,

如在ide中使用npm run serve调试,则加载的是.env.development文件

如果执行npm run build 之后发布到服务器,则加载的是.env.production文件

pageage.json的scripts部分如下

"scripts": {

    "serve": "vue-cli-service serve",

    "build": "vue-cli-service build",

    "lint": "vue-cli-service lint"

  },

在项目main.js文件可以打开查看当前的系统变量:

console.log('process.env',process.env)

设置完之后,在开始的vue.config.js代理文件中,将target指向改为: process.env.VUE_APP_BASE_URL

之后,vue会根据执行环境的不同自动加载相应的接口地址

posted on 2020-07-15 15:32  eye_like  阅读(20026)  评论(0编辑  收藏  举报