天天看點

Vue2.0設定反向代了解決跨域問題

Vue設定反向代理;

Config/index.js ----dev:{

...

proxyTable: {//設定反向代理,實作跨域.

        '/api': {

            target: 'http://192.168.1.110:8080', //設定調用接口域名和端口号别忘了加http

            changeOrigin: true,

            pathRewrite: {// 如果接口本身沒有/api需要通過pathRewrite來重寫了位址

                '^/api': '' //這裡了解成用‘/api’代替target裡面的位址,元件中我們調接口時直接用/api代替

                    // 比如我要調用'http://0.0:300/user/add',直接寫‘/api/user/add’即可 代理後位址欄顯示/

            },

            //解決跨域引起的session問題,這段代碼改變cookie 的作用于為 path="/"

            onProxyRes(proxyRes, req, res) {

                var oldCookie = proxyRes.headers['set-cookie']

                if (oldCookie == null || oldCookie.length == 0) {

                    delete proxyRes.headers['set-cookie']

                    return

                }

                var oldCookieItems = oldCookie[0].split(';')

                var newCookie = ''

                for(var i=0; i < oldCookieItems.length; ++i){

                    if(newCookie.length >0)

                        newCookie += ';'

                    if(oldCookieItems[i].indexOf('Path=') >= 0)

                        newCookie += 'Path=/'

                    else

                        newCookie += oldCookieItems[i]

                }

                proxyRes.headers['set-cookie'] = [newCookie]

            }

        }

    },

...

}

axios.defaults.withCredentials = true;

4、代理轉發cookie導緻session重置或session失效

環境:

    有2個業務接口需要轉發到82的伺服器上:

    ../user/getCode.do

    ../user/doLogin.do

現象:

    使用上述的2個接口實作使用者登入功能,首先顯示登入頁面,調用../user/getCode.do擷取驗證碼,然後使用者界面輸入使用者名、密碼和驗證碼,點選登入之後調用../user/doLogin.do接口實作登入。結果../user/doLogin.do後端總是找不到驗證碼,因為浏覽器沒有把cookie中的JSESSIONID傳遞過來。無法登入的話,後續的所有其他接口都無法調用了。

分析:

    通過chrome的network,可以看到如下資訊:

    那麼現在的問題就是為什麼在點選立即登入之後,浏覽器為什麼沒有在請求中帶上上次傳回的cookie資訊呢?

    仔細看response header中的set-cookie頭可以發現,其中有一個Path=/webserver/,說明這個cookie是有适用範圍的。隻能在/webserver/路徑下使用

    而我們代碼中使用的路徑是這麼寫的:     ../user/getCode.do,沒有包含webserver資訊,這樣浏覽器自然就認為這個請求和上次傳回的那個cookie不比對。

解決方法:

    解決方法有2中:

    一種是在請求的時候帶上/webserver/字首,比如把上文的 ../user/getCode.do改為  ../webserver/user/getCode.do;

    第二種是修改代理的實作,把82伺服器上傳回的http頭上的set-cookie内的Path改為  Path=/,代碼如下。

    在vue的webpack腳手架中的build/dev-server.js内的  Object.keys(proxyTable).forEach(function (context)  的實作改為如下形式

Object.keys(proxyTable).forEach(function (context) {

  var options = proxyTable[context]

  if (typeof options === 'string') {

    options = {

      target: options,

      onProxyRes(proxyRes, req, res) {

        //set-cookie:JSESSIONID=6F766ED2EEEBEAA9245F7F908A848857; Path=/webserver/; HttpOnly

        var oldCookie = proxyRes.headers['set-cookie']

        if(oldCookie== null || oldCookie.length==0){

          delete proxyRes.headers['set-cookie']

          return

        }

        console.log(oldCookie)

        var oldCookieItems = oldCookie[0].split(';')

        var newCookie = ''

        for(var i=0; i < oldCookieItems.length; ++i){

          if(newCookie.length >0)

            newCookie += ';'

          if(oldCookieItems[i].indexOf('Path=') >= 0)

            newCookie += 'Path=/'

          else

            newCookie += oldCookieItems[i]

        }

        proxyRes.headers['set-cookie'] = [newCookie]

        //proxyRes.headers['x-addedygc'] = 'foobar';     // add new header to response

        //delete proxyRes.headers['connection'];       // remove header from response

      }

    }

  }

  app.use(proxyMiddleware(context, options))

})

結論:

    經過試驗,以上2種方法都适用,問題解決。

 本文參考了很多大牛寫的文章,并加以總結。

http://www.ruanyifeng.com/blog/2016/04/cors.html 

http://www.cnblogs.com/strinkbug/p/6073806.html 

https://www.cnblogs.com/sxdxcj/p/9019442.html