rails api,react前端,axios,开发中的CORS不起作用
Posted
技术标签:
【中文标题】rails api,react前端,axios,开发中的CORS不起作用【英文标题】:rails api, react front end, axios, CORS in development not working 【发布时间】:2018-06-21 11:39:56 【问题描述】:我确定这个问题(或非常相似的问题)已经被问过很多次了,但我是跨域请求的新手,在搜索其他人的答案时,我无法发送基本请求从 React 前端到仅使用 rails-api 的后端,而两者都在开发服务器上本地运行。
任何解决此问题的帮助/帮助我理解为什么它不起作用将不胜感激!
前端:(如 onClick 函数处理程序,在端口 3000 上的 npm 开发服务器上运行)
function sendGetRequest()
Axios.request(
url: 'http://localhost:3001/users/2',
method: 'get',
headers:
'Content-Type': 'application/json',
'Accept': 'application/json'
,
withCredentials: true
).then(function (response)
console.log(response);
)
.catch(function (error)
console.log(error);
);
后端(rails rack-cors,在 rails puma 服务器上运行,端口 3001):
config.middleware.insert_before 0, Rack::Cors do
allow do
origins 'localhost:3000'
resource '*',
:headers => :any,
:expose => ['access-token', 'expiry', 'token-type', 'uid', 'client'],
:methods => [:get, :post, :put, :patch, :delete, :options, :head]
end
end
我已经通过 postman 和 rspec 验证了各种控制器方法都正确地响应了 JSON。
当我尝试运行它时,我收到如下错误:
"加载http://localhost:3001/users/2失败:当请求的凭据模式为'include'时,响应中的'Access-Control-Allow-Origin'标头的值不能是通配符'*'。来源'@987654322 @' 因此不允许访问。由 XMLHttpRequest 发起的请求的凭据模式由 withCredentials 属性控制。"
非常感谢!
【问题讨论】:
您的origins 'localhost:3000'
行需要改为origins 'http://localhost:3000'
(必须包含http://
协议部分)。但是,即使您进行了更改,我也不认为它会解决导致问题中出现错误消息的问题。其原因似乎是http://localhost:3001
服务器的服务器代码的其他部分已经发回了Access-Control-Allow-Origin: *
响应标头。服务器应该发回一个 Access-Control-Allow-Origin: http://localhost:3001
响应头。
@sideshowbarker 明白了 - 你是对的,添加 http 协议并不能解决问题。您知道将 Access-Control-Allow-Origin 标头发送到哪里的 rails api(大概在 rack cors gem 的某个地方)吗?
@sideshowbarker 我不太确定localhost
是否需要协议前缀。我有一个类似的设置,在没有“http://”的情况下可以正常工作。
@w_hile 浏览器肯定需要。 Access-Control-Allow-Origin: localhost:3001
响应标头与浏览器期望的 http://localhost:3001
源不匹配。该标头值需要是一个来源,它必须包含协议。
虽然 Origin 请求头和 ACAO 响应头的值确实需要包含该方案,但 rack-cors 中的 origins
节点通常与 Origin 头进行比较,以检查是否应发送 CORS 响应标头。所以在这种情况下,您确实可以指定origins localhost:3001
- 这将允许来自http://localhost:3001
和https://localhost:3001
的请求
【参考方案1】:
让我使用rack-cors
与您分享我的应用程序中的一些代码。
这是config/initializers/cors.rb
中的代码。
if Rails.application.config.x.cors_allowed_origins
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins Rails.application.config.x.cors_allowed_origins
resource '*',
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head],
credentials: true
end
end
end
上面的Rails.application.config.x.cors_allowed_origins
通过环境变量设置在config/application.rb
中,以便在开发和生产中设置不同的允许来源。
config.x.cors_allowed_origins = ENV['CORS_ALLOWED_ORIGINS']
通过这些设置,该应用程序预计将使用一个环境变量启动,该环境变量接受 SPA 的运行端口,例如CORS_ALLOWED_ORIGINS=localhost:8080 bundle exec rails s
。 localhost:8080
这里是运行 SPA 的主机。
在 SPA 方面,这是给 whatwg-fetch
的选项。抱歉,我在这里没有使用 Axios,但它会对您有所帮助。
const options =
headers:
'Content-Type': 'application/json',
'Accept': 'application/json'
,
mode: 'cors',
credentials: 'include'
;
【讨论】:
以上是关于rails api,react前端,axios,开发中的CORS不起作用的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的 axios 使用 React.useEffect 一遍又一遍地从 Rails 后端获取调用?
使用 React 时,rails api-only 应用程序中出现 401 未经授权的错误
我应该在后端(Rails API)还是前端(React/Redux)上查询和过滤
Laravel - React,强制 Axios 进行拒绝/捕获
如何从 Heroku 中托管的 Rails API 应用程序在浏览器中设置 cookie,该应用程序在 Netlify 中托管的 React 应用程序中运行前端?