Vue进阶系列--跨域

方案1:webpack

其他网址

VUE axios 跨域问题 No 'Access-Control-Allow-Origin' header is present on the requested resource._王小二的博客-CSDN博客
json - Vue Axios CORS policy: No 'Access-Control-Allow-Origin' - Stack Overflow

webpack官网(devserverproxy)

基础

其他网址

GitHub - chimurai/http-proxy-middleware
vue-cli proxyTable中跨域中pathRewrite 怎么用 - SegmentFault 思否

devServer

devServer:开发服务器代理。

proxyTable的pathRewrite

pathRewrite使用正则表达式

示例:

'proxyFor/abc':{                // 要代理的接口名
	target:'http://siwei.me',   // 要代理的根地址
	changeOrigin:true,          // 允许跨域
	pathRewrite:{'^/abc':''}    // 接口名重写
}

含义:^/abc应该拆分为“^”和“/abc”,“^”匹配字符串最开始的位置。
比如:/abc/def/gh;经过 http-proxy-middleware 的代理服务器时,会变成"/def/gh",与“target”拼接,组成:"http://siwei.me/def/gh"

使用代理之前

router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import Axios from 'axios';
import VueAxios from 'vue-axios';
import FormSubmit from "@/components/FormSubmit";

Vue.use(Router)
Vue.use(VueAxios, Axios);

export default new Router({
  routes: [
    {
      path: '/form_submit',
      name: 'formSubmit',
      component: FormSubmit
    }
  ]
})

components/FormSubmit.vue 

<template>
  <div>
    <textarea v-model='content'>
    </textarea>
    <br/>
    <input type='button' @click='submit' value='留言'/>
  </div>
</template>
<script>
export default {
  data() {
    return {
      content: ''
    }
  },
  methods: {
    submit: function () {
      this.axios.post('http://siwei.me/interface/blogs/add_comment',
        {
          content: this.content
        }
      )
        .then((response) => {
            alert("提交成功!, 刚才提交的内容是:" + JSON.stringify(response));
          },
          (response) => {
            alert("出错了")
          }
        )
    }
  }
}
</script>

config/index.js

采用默认配置。

...
module.exports = {
  dev: {

    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',

    proxyTable: {},
    ...
}

结果

使用代理之后

config/index.js

修改proxyTable

...
module.exports = {
  dev: {
    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',

    proxyTable: {
      '/abc':{                        // 要代理的接口名
        target:'http://siwei.me',     // 要代理的接口地址
        changeOrigin:true,            // 允许跨域
        pathRewrite:{'^/abc':''}      // 接口名重写
      }
    },
    ...
}

可以代理所有  //下边这样配置时,接口是啥就写啥。对本处来说:this.axios.post('/interface/blogs/add_comment',

...
module.exports = {
  dev: {
    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',

    proxyTable: {
      '/':{                         // 要代理的接口名。本处也可以用'**'
        target:'http://siwei.me',   // 要代理的接口地址
        changeOrigin:true,          // 允许跨域
      }
    },
    ...
}

可以配置多个代理接口的,就是普通的json格式。例如:

...
module.exports = {
  dev: {
    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',

    proxyTable: {
      '/abc':{            // 要代理的接口名
        target:'http://siwei.me',     // 要代理的接口地址
        changeOrigin:true,            // 允许跨域
        pathRewrite:{'^/abc':''}      // 接口名重写
      },
      '/def':{            // 要代理的接口名
        target:'http://siwei.me',     // 要代理的接口地址
        changeOrigin:true,            // 允许跨域
        pathRewrite:{'^/def':''}      // 接口名重写
      }
    },
    ...
}

router/index.js(跟上边一样)

import Vue from 'vue'
import Router from 'vue-router'
import Axios from 'axios';
import VueAxios from 'vue-axios';
import FormSubmit from "@/components/FormSubmit";

Vue.use(Router)
Vue.use(VueAxios, Axios);

export default new Router({
  routes: [
    {
      path: '/form_submit',
      name: 'formSubmit',
      component: FormSubmit
    }
  ]
})

components/FormSubmit.vue 

<template>
  <div>
    <textarea v-model='content'>
    </textarea>
    <br/>
    <input type='button' @click='submit' value='留言'/>
  </div>
</template>
<script>
export default {
  data() {
    return {
      content: ''
    }
  },
  methods: {
    submit: function () {
      this.axios.post('/abc/interface/blogs/add_comment',
        {
          content: this.content
        }
      )
        .then((response) => {
            alert("提交成功!, 刚才提交的内容是:" + JSON.stringify(response.data));
          },
          (response) => {
            alert("出错了")
          }
        )
    }
  }
}
</script>

结果

方案2:@vue/cli 3

其他网址

跨域配置(@vue/cli官网)

Vue工具系列--vue-cli-service_feiying0canglang的博客-CSDN博客

简介

跟webpack-dev-server一样用(除了配置位置不一样以外)。

注意事项

配置http格式

其他网址

使用Vue的axios vue-resource跨域不成功 但原生xhr就可以 - SegmentFault 思否
vue中使用axios的多种方式 - 简书

axios官网:https://github.com/axios/axios#using-applicationx-www-form-urlencoded-format

简介

        axios 发送请求时的数据默认是 JSON 格式的。这是导致用 axios POST 跨域出错的主要原因。

        根据 CORS 的标准,当浏览器发送跨域请求时,如果请求不是GET或者特定POST(Content-Type只能是 application/x-www-form-urlencoded, multipart/form-data 或 text/plain的一种)时,强烈要求浏览器必须先以 OPTIONS 请求方式发送一个预请求(preflight request),从而获知服务器端对跨源请求所支持 HTTP 方法。使用 axios 直接发送 POST 的跨域请求,如果web后端对 OPTIONS 的响应有问题,就会报错。

        用 axios 解决跨域的方案和你类似,不过是先把 params 转换为字符串格式了,见上边的官方用x-www-form-urlencoded格式的说明。

实例: post方法使用application/x-www-form-urlencoded格式

1.设置 headers:{ 'Content-type': 'application/x-www-form-urlencoded'}

axios.post('url',data,{headers:{ 'Content-type': 'application/x-www-form-urlencoded'}})

// 不想在每次请求都设置的话,可以集中设置下
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';

2.使用qs

仅仅第一步并没有达到想要的效果,post的body主体中还是{"age":10}这样的格式,并不是我们想要的query参数。引入Qs,这个库是axios里面包含的,不需要再下载了 

import qs from 'qs';
import axios from 'axios';

let reqUrl = 'http://xxx.com';
let reqParams = {
    name: 'aaa'
};
axios.post(url, qs.stringify({
    params: reqParams
})).then(response => {
    console.log(response);
})

其他

跨域的cookie丢失

axios默认是不让ajax请求头部携带cookie的,设置 axios.defaults.withCredentials = true 即可

猜你喜欢

转载自blog.csdn.net/feiying0canglang/article/details/113043880