无法从获取请求中获取 'Access-Control-Allow-Origin' header
Can't get 'Access-Control-Allow-Origin' header from fetch request
我正在 React 中构建一个 Chrome 扩展,它连接到后端的 Rails 6 应用程序。我希望 Rails 应用程序充当 API 并存储来自扩展程序的数据,但我无法让它接受来自我的扩展程序的请求。
这是我的扩展程序中的提取代码:
fetch('https://www.myapp.com/api/post_comment/test', {
method: 'get',
headers: {'Content-Type':'application/json'}
});
这是我在 js 控制台中不断遇到的错误:
Access to fetch at 'https://www.myapp.com/api/test' from origin
'http://localhost:3000' has been blocked by CORS policy: Response to
preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. If an opaque response serves your needs, set the request's
mode to 'no-cors' to fetch the resource with CORS disabled.
The FetchEvent for "https://www.myapp.com/api/test" resulted in a network
error response: an object that was not a Response was passed to
respondWith().
我尝试将 rack-cors gem 添加到我的 Rails 应用程序:
#Gemfile:
gem 'rack-cors'
#config/initializers/cors.rb:
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '/api/*', headers: :any, methods: [:get, :post, :patch, :put]
end
end
我还尝试在我的 Rails 应用程序控制器中手动添加 header:
before_action :cors_preflight_check
after_action :cors_set_access_control_headers
def cors_set_access_control_headers
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, PUT, DELETE, GET, OPTIONS'
headers['Access-Control-Request-Method'] = '*'
headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization'
end
# If this is a preflight OPTIONS request, then short-circuit the
# request, return only the necessary headers and return an empty
# text/plain.
def cors_preflight_check
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, PUT, DELETE, GET, OPTIONS'
headers['Access-Control-Request-Method'] = '*'
headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization'
render :text => '', :content_type => 'text/plain'
end
但我仍然遇到错误。有人知道我该如何解决这个问题吗?
如果我将 mode: 'no-cors',
添加到我的获取代码中,我可以 post 数据,但我无法检索数据。
将您的配置从 config/cors.rb
移动到 config/initializers/cors.rb
config/initializers/
中的所有文件将在 rails 启动时加载。
也可以通过 rails 6 新功能来阻止不需要的主机。
将以下代码段添加到 config/application.rb
或 config/environments/
中的 env 特定文件
config.hosts.clear
检查
在扩展程序中,您有两个来源 - 内容脚本注入的页面来源和后台脚本来源。
要使后台脚本能够连接到您的 api - 您需要将 "https://www.myapp.com/"
添加到清单的 permissions
,它不受常规 CORS 检查的约束。内容脚本可以通过 message passing 与后台对话,因此可以避免 CORS:
// from content script:
chrome.runtime.sendMessage({action: "doSomeAction"}, function(response) {
console.log(response);
});
//in background script:
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab ? "from a content script:" + sender.tab.url : "from the extension");
if (request.action == "doSomeAction") {
fetch('https://www.myapp.com/api/post_comment/test', {
method: 'get',
headers: {'Content-Type':'application/json'}
}).then(function(response){
// do something with response and pass pack to content script:
sendResponse({foo: "bar"});
});
return true; // keep message channel so sendResponse is available in
}
});
至于 rails CORS - 我首先要确保 header 存在:
curl -IX OPTIONS https://www.myapp.com/api/post_comment/test -H 'Access-Control-Request-Method: GET' -H 'Origin: http://someorigin.example.com'
这应该 return 类似于:
HTTP/2 200
server: nginx
date: Thu, 22 Oct 2020 19:50:00 GMT
access-control-allow-origin: http://someorigin.example.com
access-control-allow-methods: GET, POST, OPTIONS
access-control-expose-headers:
access-control-max-age: 7200
cache-control: no-cache
x-request-id: 5846b7400a15b19398c96bec7faac570
x-runtime: 0.001532
我正在 React 中构建一个 Chrome 扩展,它连接到后端的 Rails 6 应用程序。我希望 Rails 应用程序充当 API 并存储来自扩展程序的数据,但我无法让它接受来自我的扩展程序的请求。
这是我的扩展程序中的提取代码:
fetch('https://www.myapp.com/api/post_comment/test', {
method: 'get',
headers: {'Content-Type':'application/json'}
});
这是我在 js 控制台中不断遇到的错误:
Access to fetch at 'https://www.myapp.com/api/test' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
The FetchEvent for "https://www.myapp.com/api/test" resulted in a network error response: an object that was not a Response was passed to respondWith().
我尝试将 rack-cors gem 添加到我的 Rails 应用程序:
#Gemfile:
gem 'rack-cors'
#config/initializers/cors.rb:
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '/api/*', headers: :any, methods: [:get, :post, :patch, :put]
end
end
我还尝试在我的 Rails 应用程序控制器中手动添加 header:
before_action :cors_preflight_check
after_action :cors_set_access_control_headers
def cors_set_access_control_headers
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, PUT, DELETE, GET, OPTIONS'
headers['Access-Control-Request-Method'] = '*'
headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization'
end
# If this is a preflight OPTIONS request, then short-circuit the
# request, return only the necessary headers and return an empty
# text/plain.
def cors_preflight_check
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, PUT, DELETE, GET, OPTIONS'
headers['Access-Control-Request-Method'] = '*'
headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization'
render :text => '', :content_type => 'text/plain'
end
但我仍然遇到错误。有人知道我该如何解决这个问题吗?
如果我将 mode: 'no-cors',
添加到我的获取代码中,我可以 post 数据,但我无法检索数据。
将您的配置从 config/cors.rb
移动到 config/initializers/cors.rb
config/initializers/
中的所有文件将在 rails 启动时加载。
也可以通过 rails 6 新功能来阻止不需要的主机。
将以下代码段添加到 config/application.rb
或 config/environments/
config.hosts.clear
检查
在扩展程序中,您有两个来源 - 内容脚本注入的页面来源和后台脚本来源。
要使后台脚本能够连接到您的 api - 您需要将 "https://www.myapp.com/"
添加到清单的 permissions
,它不受常规 CORS 检查的约束。内容脚本可以通过 message passing 与后台对话,因此可以避免 CORS:
// from content script:
chrome.runtime.sendMessage({action: "doSomeAction"}, function(response) {
console.log(response);
});
//in background script:
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab ? "from a content script:" + sender.tab.url : "from the extension");
if (request.action == "doSomeAction") {
fetch('https://www.myapp.com/api/post_comment/test', {
method: 'get',
headers: {'Content-Type':'application/json'}
}).then(function(response){
// do something with response and pass pack to content script:
sendResponse({foo: "bar"});
});
return true; // keep message channel so sendResponse is available in
}
});
至于 rails CORS - 我首先要确保 header 存在:
curl -IX OPTIONS https://www.myapp.com/api/post_comment/test -H 'Access-Control-Request-Method: GET' -H 'Origin: http://someorigin.example.com'
这应该 return 类似于:
HTTP/2 200
server: nginx
date: Thu, 22 Oct 2020 19:50:00 GMT
access-control-allow-origin: http://someorigin.example.com
access-control-allow-methods: GET, POST, OPTIONS
access-control-expose-headers:
access-control-max-age: 7200
cache-control: no-cache
x-request-id: 5846b7400a15b19398c96bec7faac570
x-runtime: 0.001532