使用Vue的axios vue-resource跨域不成功 但原生xhr就可以

使用Vue的Ajax组建axios vue-resource跨域都不成功

但原生xhr就能跨域成功?

xhr请求:
axios

使用axios的请求:
图片描述

错误提示(axios的):
图片描述

XMLHttpRequest cannot load http://ss.net/auth. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://vue.js:8080' is therefore not allowed access.

createError.js?f777:15 Uncaught (in promise) Error: Network Error
    at createError (eval at <anonymous> (build.js:899), <anonymous>:15:15)
    at XMLHttpRequest.handleError (eval at <anonymous> (build.js:878), <anonymous>:87:14)

code:

    export default {
        data() {
            return {
                mes: '',
            }
        },
        methods: {
            logIn: function (mes) {
                //axios
                this.axios({
                    method: 'post',
                    url: 'http://ss.net/auth',
                    data: {
                        firstName: 'Fred',
                        lastName: 'Flintstone'
                    },
                    withCredentials: false
                });

                //xhr
                var request = new XMLHttpRequest();
                request.open('POST', 'http://ss.net/auth', true);

                request.onload = function() {
                    if (this.status >= 200 && this.status < 400) {

                    }
                };

                request.send();

            },
        },
    }

后端加了一个中间件,测试应该是没问题的:

        return $next($request)
            ->header('Access-Control-Allow-Origin', '*')
            ->header('Access-Control-Allow-Credentials', 'false')
            ->header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, OPTIONS')
            ->header('Access-Control-Allow-Headers', 'Content-Type, Accept, Authorization, X-Requested-With, Origin, Accept');

后端已经设置了CROS,一天了没整明白,有知道的吗..

阅读 44.6k
4 个回答

刚好也遇到了类似的问题,已解决,试着解答下你的问题。

首先,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 的响应有问题,就会报错。我没有 Node 环境,对 Node 也不了解,所以没法验证你的配置是否OK,但参考我 Nginx 上的配置,我感觉你在 Allow-Headers 里再加点内容可能会OK?

另外,至于为何 XHR 可以。我猜也是跟数据格式有关,XHR 应该是 form-urlencoded 格式吧。因为你的截图看不到 Form Data,所以不好下结论。

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

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);
})
#
# Wide-open CORS config for nginx
#
location / {
     if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        #
        # Custom headers and headers various browsers *should* be OK with but aren't
        #
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
        #
        # Tell client that this pre-flight info is valid for 20 days
        #
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
     }
     if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
     }
     if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
     }
}

官方用x-www-form-urlencoded格式的说明

CORS标准的说明

加了一个header,暂时解决了:

headers: {'Content-Type': 'application/x-www-form-urlencoded'}

具体原因参考这个回答:
https://segmentfault.com/q/10...

我今天才折腾过这个 实际上cors请求会发送两个 第一个是options请求 你看看能不能正确响应并且带有cors相关的首部

图片描述

nginx 如此设置就可以访问,亲测有用。

推荐问题
宣传栏