Axios: 无法使跨站点 POST 工作

创建于 2016-01-11  ·  70评论  ·  资料来源: axios/axios

你好,

感谢您做的伟大工作。
尽管那是一些针对跨站点请求的版本,但我仍然无法让它工作。 我翻阅了以前的帖子并尝试添加:

  • 跨域:真
  • xDomain: 真
    *xDomainRequest: 真

到配置。 他们都没有工作。 (如果此功能确实可用,更新自述文件会有所帮助。)

请尽快告知。 谢谢你。

最有用的评论

这么大的问题怎么不解决?

所有70条评论

此外,我还在配置中将 withCredentials 设置为 true。

我刚刚也遇到了这个问题,它似乎只发生在 Mac 上。 我花了三天三夜的时间试图调试我的网络,并一时兴起决定使用 vanilla XHR 请求尝试这个,并意识到问题不是我的网络,而是 axios。

我也在做跨站点请求,凭据设置为 true。 查看网络请求,您会得到一个 ERR_EMPTY_RESPONSE,这就像请求在离开浏览器之前就失败了。

这是我的配置:

const myApi = axios.create({
  baseURL: 'http://someUrl/someEndpoint',
  timeout: 10000,
  withCredentials: true,
  transformRequest: [(data) => JSON.stringify(data.data)],
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
  }
});'

如果有机会,我会尝试进一步研究这个问题。

哦,很好,我没有疯。 :) 如果可能,请研究一下。

原来我的问题与 Axios 无关。 Cisco Anyconnect 阻止了来自我机器的选项请求......因为原因?

跨域请求不需要任何额外的配置。 对于较旧的 IE,它将回退到使用XDomainRequesthttps://github.com/mzabriskie/axios/blob/master/lib/adapters/xhr.js#L22

你能提供更多细节吗? 什么浏览器,操作系统,axios 版本,任何错误信息。

我不能代表 Jenny,但是这个库确实会导致请求被 Cisco Anyconnect 默认安全阻止,这意味着其他安全设置也可能会这样做。 我正在努力追踪这一点,但到目前为止还没有运气。

这可以通过在安装有 cisco Anyconnect 和可能的其他 VPN 客户端的 mac 上发出跨站点请求来重现。

我的环境是:

  • Axios 0.8.1
  • 埃尔卡皮坦
  • 铬合金
  • 错误消息:“请求的资源上不存在‘Access-Control-Allow-Origin’标头。因此不允许访问Origin‘http://localhost :3000’。”

请注意,相同的请求适用于 curl。

感谢您查看这个!

使用 CORS 会向服务器发出预检请求,以查看是否允许该请求。 您需要通过设置标题Acces-Control-Allow-Origin: *来让您的服务器响应以OPTIONS作为请求方法的请求,这将允许来自任何来源的请求。 或者,您可以只允许某些来源Acces-Control-Allow-Origin: http://example.com

是的,我明白。 但是服务器不是我的。 我正在使用 Baas(后端即服务)。 他们已经将我的域添加到允许列表中。 我已经检查过使用上述 Baas 的其他人没有遇到过这样的问题。

我只是要关闭您提供的错误消息,但基于此,听起来您 baas 并不适合您。 使用 curl 不会失败,因为跨源安全只是浏览器中的一个限制。

您能否在浏览器中打开网络选项卡并分享您对 OPTIONS 请求的响应? 希望看到响应数据和标头将有助于调试此问题。

谢谢

以下是标题:

image

当我使用 axios 从他们的 API 获取我的用户配置文件时,这是来自 GitHub 的响应标头:

screen shot 2016-01-19 at 11 36 54 am

可以看到 GitHub 添加了Access-Control-Allow-Origin: * 。 您的 Baas 的响应缺少任何Access-Control类型的标头。

我明白了,嗯。 抱歉回复太晚了。 让我再研究一下。 非常感谢你。

我不确定我所看到的是否相关。 基本上,我可以向我们的远程服务器发送一个 auth 请求并取回一个 cookie,但是随后对服务器的调用 _don't_ 将 cookie 与它们一起发送,从而导致错误。

以下是POST调用登录的标题:
login

现在跟进GET调用:
verify

origin下列出的 IP 地址是我自己的,所以这应该不是问题。 如果这是错误的地方,我很高兴提出一个新问题,或附加到适当的现有问题。

作为新的皱纹; 我已经使用直接 XHR 测试了后续GET调用,并且 cookie 发送得很好。 但是,通过 Axios 执行相同的调用会导致我上面提到的相同问题。

啊。 请无视 - 我没有按预期通过 Axios 发送东西 :)

我也面临同样的问题。
选项调用通过,但 POST 调用卡在 cors 中。
http://stackoverflow.com/questions/36907693/axios-cors-issue-with-github-oauth-not-getting-access-token

这么大的问题怎么不解决?

+1

+1

+1

+1

+1

+1

+1

@dsacramone您看到的问题是什么? 似乎报告的大多数问题都是服务器问题或误报问题。 如果有我可以查看的可重现错误,我很乐意进行修复。

也得到这个

XMLHttpRequest 无法加载https://en.wikipedia.org/w/api.php?action=opensearch&format=json&search=fish。 请求的资源上不存在“Access-Control-Allow-Origin”标头。 因此,不允许访问 Origin ' http://localhost :3000'。

还使用 fetch 来获取它来记录。 我认为它的 chrome 最近使他们的请求设置策略更加严格,我认为它需要某种标题(不确定是什么)。

这是一些示例(均通过 https 提供)

示例 1 - 工作正常

axios.get('https://randomuser.me/api/')
  .then(function (response) {
    console.log(response.data);
  })
  .catch(function (error) {
    console.log(error);
  });

示例 2 - 不工作 - 显示错误?

axios.get('https://en.wikipedia.org/w/api.php?action=opensearch&format=json&search=fish')
  .then(function (response) {
    console.log(response.data);
  })
  .catch(function (error) {
    console.log(error);
  });

这是错误响应

[object Error] {
  config: [object Object] {
    data: undefined,
    headers: [object Object] { ... },
    maxContentLength: -1,
    method: "get",
    timeout: 0,
    transformRequest: [object Object] { ... },
    transformResponse: [object Object] { ... },
    url: "https://en.wikipedia.org/w/api.php?action=opensearch&format=json&search=fish",
    validateStatus: function validateStatus(status) {
      return status >= 200 && status < 300;
    },
    xsrfCookieName: "XSRF-TOKEN",
    xsrfHeaderName: "X-XSRF-TOKEN"
  },
  response: undefined
}

可能相关的东西在 transformResponse 中? 我想知道 PROTECTION_PREFIX 位是什么意思?

[object Object] {
  0: function transformResponse(data) {
      /*eslint no-param-reassign:0*/
      if (typeof data === 'string') {
        data = data.replace(PROTECTION_PREFIX, '');
        try {
          data = JSON.parse(data);
        } catch (e) { /* Ignore */ }
      }
      return data;
    }
}

甚至尝试

模式:'no-cors'
在 fetch 中仍然给出这个错误

我确定答案非常简单,只需要某种标题,只是不确定会继续玩什么。

维基百科 api 可能只是一个奇怪的例子,其他人也有同样的错误?

我删除此代码,可以工作: axios.defaults.withCredentials = true

我让维基百科 api 与jsonp一起工作

var jsonp = require('jsonp');

// search for 'frog'
jsonp('https://en.wikipedia.org/w/api.php?action=opensearch&search=frog&format=json', null, function (err, data) {
  if (err) {
    console.error(err.message);
  } else {
    console.log(data);
  }
});

不需要额外的配置。

使用 axios 出现相同的错误。 这是我的 React 组件:

import React, { Component } from 'react'
import axios from 'axios'

export default class User extends Component {
  constructor(props){
    super(props)

    // axios.defaults.withCredentials = true

    const config = {
    method: 'get',
    url: 'https://api.airbnb.com/v2/users/2917444?client_id=3092nxybyb0otqw18e8nh5nty&_format=v1_legacy_show',
    headers: {'X-Requested-With': 'XMLHttpRequest'},
    responseType: 'json',
    withCredentials: true,
  }

    axios.request(config)
      .then(response => { console.log('response: ', response) });

  }

  render() {
    return (
      <div>User</div>
    )
  }
}

_注意:我可以通过 Node 请求完美地访问 API。_

遇到了与net::ERR_EMPTY_RESPONSE (我的服务器处理所有 CORS 标头,包括 OPTIONS 就好了)。 这很奇怪,因为在 iOS10 Safari 上,完全相同的代码没有问题。 将尝试自己进行更多调查,以了解如何解决此问题。

在装有最新版 chrome 的旧 Mac (10.11) 上,我无法使用完全相同的代码重现此错误。 这确实很奇怪。 您可以通过访问这个非常简单的应用程序来重现: http : 这里。在某些机器上不会有错误,它会重定向您登录。在其他机器上它不会重定向,并将让您留在主页上。

解决了我的错误。 对我来说,在应用程序启动时config.headers的标头分配一个空值是一个问题(它从本地存储中提取一个值,最初什么都没有)。 当值为空时将值分配为空字符串可以解决问题。 我想知道这是否可以或应该在 axios 中处理(不确定是否有值将 null 标头传递给 xhr,如果它有时会中断)。

对于其他有类似问题的人,我发现某些 VPN 客户端也可以阻止 OPTIONS 请求(请参阅此处

误导性的 CORS 错误仍在 axios 中。 fetch polyfill 支持mode: 'no-cors'来解决这个问题。

我们需要做这些类型的请求,以对我们操作的其他环境中的机器以及不同端口的同一台机器上的机器发出请求!

@dreki请提供您提到的问题的描述。

当服务器根本不接受来自您的源的请求时,您无法在客户端做任何事情。 如果可以的话,我们这里会有一个巨大的安全漏洞(“我们”是指整个互联网)......

我认为 axios 在这里的行为和反应完全符合。

重要的 Response 标头是Access-Control-Allow-Origin ,它基本上设置了允许调用此服务器端服务的有效来源。 如果您的客户端没有从这些配置的任何源调用,请求将被拒绝,控制台错误如下:

XMLHttpRequest 无法加载http://localhost :8080/v1/api/search?q=candles。 请求的资源上不存在“Access-Control-Allow-Origin”标头。 因此,不允许访问 Origin ' http://localhost :9999'。

你不在客人名单上。

解决了我的问题。
试图从localhost:8080上的 vue 应用程序访问localhost:3000上的 express api,但返回错误。
原来你需要添加http://才能让它工作。
所以在进行开发测试时使用http://localhost:3000而不是localhost:3000

我对 wikmedia api 有同样的问题。 查看他们的 CORS 页面 (https://www.mediawiki.org/wiki/Manual:$wgCrossSiteAJAXdomains) 我在请求中添加了 origin=* 并解决了问题。

axios.get('https://en.wikipedia.org/w/api.php?action=opensearch&format=json&origin=*&search=Albert') .then(function(res) { console.log(res); }) .catch(function(err) { console.log('Error: =>' + err); })

尽管我收到了可怕的 cors 错误消息,但我的请求还是到达了服务器。

XMLHttpRequest cannot load "...url here...". No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.

Axios 团队,你能修复吗???

@mellogarrett这不是 axios 相关问题。 阅读: https :

重要引用:

“出于安全原因,浏览器会限制从脚本内部发起的跨域 HTTP 请求。例如,XMLHttpRequest 和 Fetch 遵循同源策略。因此,使用 XMLHttpRequest 或 Fetch 的 Web 应用程序只能向其自己的域发出 HTTP 请求。”改进 Web 应用程序,开发人员要求浏览器供应商允许跨域请求。”

许多遇到此问题的人可能没有让服务器响应 OPTIONS 请求。 确保您有用于 OPTIONS 和 POST 请求的处理程序(带有 CORS 标头)。 客户端 (axios) 将首先 ping OPTIONS,然后执行 POST。

我在 Firefox 上有同样的错误,但在 Chromium 上没有。 然后我想起 NoScript 在那里(在 Firefox 中)阻止了对远程服务器的请求。 如果您安装了 NoScript(或类似插件),请先检查。
就我而言,该问题与 Axios 无关。 感谢您做的伟大工作。

对于使用谷歌搜索解决此问题的其他人,我遇到了所有相同的症状,但将问题追溯到服务器上的 php.ini 设置。

我的预检 OPTIONS 请求成功,然后是正确的 POST 请求,但我仍然收到类似于@mellogarrett 的No 'Access-Control-Allow-Origin' header is present on the requested resource... 。 这看起来很奇怪,所以我使用了一个Chrome 插件来暂时禁用 CORS 保护。 在那之后,我可以看到问题实际上是一个 PHP 错误:

Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version. To avoid this warning set 'always_populate_raw_post_data' to '-1' in php.ini and use the php://input stream instead. in Unknown on line 0

这篇文章有更多关于这个问题的信息,但简而言之,如果你使用的是 PHP 5.6,你应该在你的 php.ini 中取消注释always_populate_raw_post_data并设置为-1 。 希望这可以为其他人节省几个小时的故障排除时间 🤓

@daltonamitchell似乎我遇到了同样的问题(条件表明这是同一个问题)。 但我想知道:您是如何确定原始帖子数据错误是问题所在的? 使用您提到的 chrome 插件时,CORS 请求通过,一切正常。 但是即使标题设置正确,没有插件我也无法让它工作。 因此,可能只是没有显示弃用消息,但问题可能仍然存在......? 你能给一些建议如何检查吗?

@RT-TL 该插件仅用于查看响应内容,而不会被 CORS 阻止。 就我而言,出于测试目的,我只是返回一个像Hello World这样的字符串,所以一旦我禁用了 CORS,我就会看到类似

Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version. To avoid this warning set 'always_populate_raw_post_data' to '-1' in php.ini and use the php://input stream instead. in Unknown on line 0
Hello World

通过在控制器方法的顶部添加error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE)error_reporting(E_ALL)来确保启用了PHP 警告。 如果您仍然没有看到任何内容,我将尝试返回一些简单的 JSON 响应以检查它们是否符合预期。

有人还在遇到这个问题吗? 我遇到了同样的情况:

const instance = axios.create({
    baseURL: 'http://localhost/',
    responseType: 'json',
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'Authorization': 'test',
        'X-Test': 'testing'
    }
})
axios.get('v2/portal/bar/foo?')

响应头

HTTP/1.1 401 Unauthorized
Server: nginx/1.11.10
Date: Fri, 24 Mar 2017 07:12:13 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 0
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, PUT, DELETE, GET, OPTIONS
Access-Control-Allow-Headers: *

请求头

OPTIONS /v2/portal/bar/foo? HTTP/1.1
Host: localhost
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://localhost:3000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36
Access-Control-Request-Headers: authorization,content-type,x-test
Accept: */*
Referer: http://localhost:3000/dashboard/report
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: en-US,en;q=0.8,fr;q=0.6,nl;q=0.4,zh-TW;q=0.2,zh;q=0.2,zh-CN;q=0.2

我不明白为什么我的标题都没有被正确发送。

同样的问题, OPTIONS 请求已发出,但 POST 请求未发出。

TLDR:获取有效,除非我使用JSON.stingify否则 axios 无效

所以我也看到了这个错误的变体,其中 OPTIONS 返回 200 并为跨源请求设置了标头,但没有进行 POST。 我使用这个扩展,它开始按预期工作。 但我很确定这里存在某种问题。 看看我的要求:

我的服务器正在回复Access-Control-Allow-Origin: *
以下是所有带有代码和屏幕截图的示例:

轴:

axios.post('http://localhost:3001/card', { test: 'test' })

axios_cors


拿来:

    return fetch('http://localhost:3001/card', {
      method: 'POST',
      body: { test: 'test' },
    })

fetch_no_stringify

JSON.stringify

    return fetch('http://localhost:3001/card', {
      method: 'POST',
      body: JSON.stringify({ test: 'test' }),
    })

fetch_cors

我能够通过JSON.stringify -ing 我的数据来使 axios 工作,如下所示:

    return axios.post('http://localhost:3001/card', JSON.stringify({ test: 'test' }));

axios_json_stringify

遇到了与@zlyi建议的那样,我刚刚添加了axios.defaults.withCredentials = true; ,一切都按预期开始工作。

尝试了所有方法,仍然有问题。 :(

尝试了所有方法,仍然有问题。 :(

通过将以下内容添加到 .htaccses 来管理该问题:

<IfModule mod_headers.c> 
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type" 
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS" 
</IfModule>

我能够通过使用代理来解决这个问题。 将代理添加到package.json

{
    "proxy": "http://some-url/some-endpoint"
}

然后请求:

axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response)
  })
  .catch(function (error) {
    console.log(error)
  })

这是一个服务器端问题,需要在您的响应标头中包含'Acces-Control-Allow-Origin': '*' 。 如果您使用 Express,可以使用npm-cors来实现更健壮/优雅的实现。

+1 @ProfNandaa
我在本地服务器中创建了一个导出

# cors.js file
module.exports = (req, res, next) => {
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
}

那么我分配:
``
const cors = require('cors');
router.use(cors);
````
现在继续……谢谢

当服务器不接受 OPTION 请求时会发生错误。

对于那些评论说“将 OPTION 请求处理添加到您的服务器”的评论,这是行不通的。 我正在运行一个启用了 OPTION 请求处理的本地环境。

我和上面的用户一样遇到了这个问题,其中Axios.post(url, obj)返回了 CORS 403 禁止错误,但将其更新为Axios.post(url, JSON.stringify(obj))工作正常。

我只是在做一个简单的教程项目,并且在访问各种 api 时遇到了问题。 我发现唯一可行的解​​决方案是上面 thiagodebastos 提到的解决方案。

我只是将 jsonp 替换为 get 并且我能够访问数据。

我遇到了这个问题,koa-cors 是一个简单的解决方案! (根据 ProfNandaa 的 Express 用户的 npm-cors)

对于那些仍然有问题的人: Axios 可以与 CORs一起JSON.encoded ,并且 cookie 发送并正确保存,只要 Axios 和响应请求的服务器配置正确。

经历了一些令人沮丧的反复试验,但我们有跨域请求与 Axios 一起工作正常。

几点:

为了使请求起作用,请确保

  • 服务器响应 OPTIONS 请求,就好像响应不是 200 并且设置了所有正确的标头一样, “预检”请求将失败。

  • 使用正确的标头发出请求,服务器使用所有必需的标头进行响应。

  • 如果需要 cookie/授权标头或 TLS 客户端证书,请为 Axios 请求发送 allowCredentials 为 true。 这可以作为默认值 ( axios.defaults.withCredentials = true ) 或每个请求完成。

示例成功的请求标头

Access-Control-Request-Headers: Content-Type
Access-Control-Request-Method: GET

示例成功响应标头

Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
Access-Control-Allow-Origin: http://your-origin-url.com

我们逐渐添加了响应头,发现我们有各种不同的、难以诊断的错误和不同组合的意外行为

没有Access-Control-Allow-Credentials: true cookie 就不会被发送或持久化,这在阅读该标题

通读本文档会有所帮助。

任何有问题的人, ...Allow-Headers: Content-Type都很重要。

Access-Control-Allow-Origin: '*'
Access-Control-Allow-Methods: ...
Access-Control-Allow-Headers: Content-Type, Accept

我使用名为“Allow-Control-Allow-Origin: *”的 chrome 扩展
希望它可以帮助你的问题。
2017-07-19 14 06 37

对于不明白为什么 Axios 无法修复此错误的人:

这不是 Axios 的问题。 是浏览器的问题。 浏览器中的 JS 将拒绝对没有设置正确标头的服务器的请求。 如果您在客户端上将它与 React 之类的东西一起使用,请不要混淆,这不是 React 或 Axios 问题,它只是浏览器遵守 CORS 标准。

JakeElder 很好地描述了您需要在 API 的服务器端执行的操作: https :

如果您无法控制您尝试访问的服务器,那么您应该创建一个代理服务器来为您获取内容并使用正确的标头返回它。

不知道为什么要实施这个。 当您只想向服务器发出请求以获取一些信息但不能因为服务器没有特定的标头集时,这确实很烦人。 似乎限制性极强。 那好吧 ...

@robins-eldo 再一次,我不相信你是对的。

我的原评论:

For those commenting saying "Add OPTION request handling to your server", that does not work. I'm running a local environment that has OPTION request handling enabled.

I experienced this issue identically as a user above, where Axios.post(url, obj) returned the CORS 403 forbidden error, but updating that to Axios.post(url, JSON.stringify(obj)) worked correctly.

如果它实际上是服务器问题,而不是 Axios 问题,则将对象字符串化不会有任何影响,因为无论哪种方式 OPTIONS 请求都会失败。

@亚历山大班克斯

不确定 OPTION HTTP 方法,但我的具体问题是我有一个 React 客户端尝试 POST 到我编写的内部 API(内部 API 是这里的服务器)。 我一直收到这个错误: Failed to load resource: Origin http://localhost:7149 is not allowed by Access-Control-Allow-Origin. XMLHttpRequest cannot load http://localhost:8902/user-login due to access control checks.

我认为这可能是 Axios 的问题,所以我尝试使用 Unirest 并不断收到相同的错误。 所以我想它一定是别的东西。 不确定这是浏览器问题还是 React 问题,但是一旦我将以下内容添加到我的 API 服务器(这是一个 Nodejs + Express API),一切都开始在客户端同时使用 Axios 和 Unirest:

app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); next(); });

也许我对这里幕后实际发生的事情的理解有些有限,但是,服务器上的这段代码为我解决了问题。

确保您的服务器没有过多限制源访问,如果您想绕过 no-cors,请尝试以下操作:

    return axios(url, {
      method: 'POST',
      mode: 'no-cors',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
      withCredentials: true,
      credentials: 'same-origin',
    }).then(response => {
    })

我认为这里有些人对 CORS 的工作方式感到困惑。 然而,最初的问题不是关于 CORS,或者至少这应该是重要的问题。 我的意思是,当您正确配置了 CORS 但即使 Post 不起作用,那么这是一个需要报告的问题,而不是如何正确配置服务器

API 表现得很奇怪。 所有 cors GET 请求都使用“凭据:真实”。
对于 POST 请求,同源请求在没有字符串化数据对象的情况下工作,而对于 CORS POST 请求,当我对数据对象进行字符串化时也开始工作。

没有得到确切的原因,但问题已为我解决。

我很抱歉,但我正在锁定这个线程,因为我们似乎在围绕同一主题做圈子。 如果您有另一个问题中未涵盖的特定问题(由于配置错误导致的一般 CORS 问题、POST 请求作为 JSON 而不是表单 urlencoded 发送等),请打开一个包含特定详细信息的新问题。

此页面是否有帮助?
0 / 5 - 0 等级