为何出现跨域问题以及解决办法

问题
我们本地调试一般都是 npm run serve,然后打开 本机ip:8080(localhost:8080)对吧,这时候我们要调接口调试,后端的接口的地址可能在测试环境,也可能是自己电脑的 ip,总之不是你的 lcoalhost:8080,那么你调接口就会产生跨域,那么怎么办呢?就需要proxy出场了。
首先,proxyTable是我们在本地开发环境中调试接口用的,目的是为了解决本地跨域的问题,在线上的生产环境是没用的!

本地代理是开发环境才会生效,打包为生产环境后会自动失效,打包之后会出现跨域,是因为后台接口服务没有配置响应头的跨域机制,以java为例(response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, client_id, uuid, Authorization")),当然,如果后台服务本身设计就是为了安全不开放跨域访问,那可以将打包之后的前端代码放在nginx内,并设置反向代理到对应的接口服务即可

问:
为什么开发阶段才需要解决跨域,项目发布到生产环境就proxy的配置就无效了?
答:
同源策略是浏览器需要遵循的标准,而如果是服务器向服务器请求就无需遵循同源策略。
一般前端项目最后都会打包到和接口地址相同的服务器上,此时同源不会出现跨域。并且,前端是无法解决真正的跨域问题的。proxy根本不能解决跨域,最终要跨域还是要后端配合。proxy只是前端在开发的时候,方便开发使用的东西而已,打包后就无效了。

vue-cli的proxyTable用的是http-proxy-middleware,它是http代理中间件,它依赖node.js,基本原理是用服务端代理解决浏览器跨域。
该中间件本质上是在本地开了一个服务器dev-server,所有的请求都通过这里转发出去,即把浏览器的发送请求代理转发到代理服务器上,再由代理服务器发送请求给目标服务器,从而解决跨域问题。

原理
vue 中的 proxy 就是利用了 Node 代理,原理还是因为服务器端没有跨域这一说嘛,也是用了这么一个插件 地址。

跨域之proxyTable——在开发和生产环境的不同配置:
https://blog.csdn.net/bonjourjw/article/details/95058069

image.png
 // 如果你想看代理后的路径
        onProxyReq: function (onProxyReq, req, res) {
          console.log('原相对路径' + req.originalUrl, '代理相对路径:' + req.path)
          // 这里的输出是自己配的,就是说开发环境控制台看到的地址,proxy代理成的样子,打印:http://localhost:9528/dev-api/manage/tFmAuthPlan/query
          console.log('前端请求url', onProxyReq._headers.origin + req.originalUrl)
          // 代理配置的目标地址,打印: http://192.168.0.223:18181/ad2api/manage/tFmAuthPlan/query
          console.log(
            '目标请求url2',
            onProxyReq.agent.protocol + '//' + onProxyReq._headers.host + onProxyReq.path
          )
        }

个人理解proxyTable中跨域中pathRewrite的用法
问: proxyTable 里面的pathRewrite里面的 ,^/api 什么意思?
答: 用代理,首先你得有一个标识,告诉他你这个连接要用代理,不然的话,可能你的 html,css,js这些静态资源都跑去代理.所以我们只要接口用代理,静态文件用本地
'/api': 就是告诉node,我接口只要是 '/api' 开头的请求才用代理,所以你的接口就要这么写 /api/xx/xx,最后代理的路径就是http://xxx.xx.com/api/xx/xx。可是不对啊,我正确的接口路径里面没有/api啊,所以就需要 pathRewrite用'^/api'把'/api'去掉这样既能有正确标识,又能在请求接口的时候去掉api。

Node中间件代理(两次跨域)
代理服务器,需要做以下几个步骤:

  • 接受客户端请求 。

  • 将请求 转发给服务器。

  • 拿到服务器 响应 数据。

  • 将响应 转发给客户端。


    image.png

nginx反向代理
实现原理类似于Node中间件代理,需要你搭建一个中转nginx服务器,用于转发请求。

使用nginx反向代理实现跨域,是最简单的跨域方式。只需要修改nginx的配置即可解决跨域问题,支持所有浏览器,支持session,不需要修改任何代码,并且不会影响服务器性能。

实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录。
配置nginx代理:https://blog.csdn.net/chpswg/article/details/105368938

————————————————

复习一下跨域的解决方案
jsonp
cors
Node中间件代理(两次跨域)
nginx反向代理

CORS支持所有类型的HTTP请求,是跨域HTTP请求的根本解决方案
JSONP只支持GET请求,JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。
不管是Node中间件代理还是nginx反向代理,主要是通过同源策略对服务器不加限制。
日常工作中,用得比较多的跨域方案是cors和nginx反向代理
————————————————

vue项目打包后 使用nginx部署
https://blog.csdn.net/superKM/article/details/100148095

vue开发环境配置跨域,一步到位

我的写法总结:
①api.js:
如果后端做了跨域处理,则这里可以直接写成测试环境地址:

 axios.defaults.baseURL = 'http://tshn.2windao.com:8897/filemanage';

如果跨域,可以在这里配置基础url,然后在vue.config.js里使用proxy反向代理

axios.defaults.baseURL =process.env.NODE_ENV === 'production' ? '/' : '/api/filemanage';

②vue.config.js

  devServer: {
    host: '0.0.0.0', //局域网和本地访问
    open: true,
    overlay: {
      warnings: false,
      errors: true,
    },
    proxy: {
      ['/api']: {
        target: 'http://record.2windao.com:8897',
        changeOrigin: true,
        pathRewrite: {
          ['^/api']: '',
        },
      },
    },
  },

本地测试地址是没有含有api的,所有,pathRewrite进行重写地址,把api替换成空字符“ ”。

你可能感兴趣的:(为何出现跨域问题以及解决办法)