提问人:Jignesh 提问时间:6/15/2018 最后编辑:sideshowbarkerJignesh 更新时间:12/13/2022 访问量:555394
跨域读取阻塞 (CORB)
Cross-Origin Read Blocking (CORB)
问:
我已经使用Jquery AJAX调用了第三方API。我在控制台中收到以下错误:
跨域读取阻止 (CORB) 阻止了 MIME 类型为 application/json 的跨域响应 MY URL。有关详细信息,请参阅 https://www.chromestatus.com/feature/5629709824032768。
我使用了以下代码进行 Ajax 调用:
$.ajax({
type: 'GET',
url: My Url,
contentType: 'application/json',
dataType:'jsonp',
responseType:'application/json',
xhrFields: {
withCredentials: false
},
headers: {
'Access-Control-Allow-Credentials' : true,
'Access-Control-Allow-Origin':'*',
'Access-Control-Allow-Methods':'GET',
'Access-Control-Allow-Headers':'application/json',
},
success: function(data) {
console.log(data);
},
error: function(error) {
console.log("FAIL....=================");
}
});
当我签入 Fiddler 时,我得到了响应中的数据,但没有在 Ajax 成功方法中。
请帮帮我。
答:
响应标头通常在服务器上设置。设置为在服务器端'Access-Control-Allow-Headers'
'Content-Type'
评论
您必须在服务器端添加 CORS:
如果您使用的是 nodeJS,则:
首先,您需要使用以下命令进行安装:cors
npm install cors --save
现在,将以下代码添加到应用启动文件中,例如 (app.js or server.js
)
var express = require('express');
var app = express();
var cors = require('cors');
var bodyParser = require('body-parser');
//enables cors
app.use(cors({
'allowedHeaders': ['sessionId', 'Content-Type'],
'exposedHeaders': ['sessionId'],
'origin': '*',
'methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
'preflightContinue': false
}));
require('./router/index')(app);
评论
在大多数情况下,被阻止的响应不应影响网页的行为,并且可以安全地忽略 CORB 错误消息。例如,当被阻止的响应的正文已为空时,或者当响应将传递到无法处理它的上下文(例如,将 HTML 文档(如 404 错误页面)传递到标记)时,可能会出现警告。
https://www.chromium.org/Home/chromium-security/corb-for-developers
我必须清理浏览器的缓存,我在此链接中阅读,如果请求得到空响应,我们会收到此警告错误。我在我的请求中得到了一些 CORS,所以这个请求的响应是空的,我所要做的就是清除浏览器的缓存,然后 CORS 就消失了。我收到 CORS,因为 chrome 已将 PORT 号保存在缓存中,服务器只会接受,而我正在这样做,因为缓存。localhost:3010
localhost:3002
从问题中尚不清楚,但假设这是在开发或测试客户端上发生的事情,并且鉴于你已在使用 Fiddler,你可以让 Fiddler 使用允许响应进行响应:
- 在 Fiddler 中选择问题请求
- 打开选项卡
AutoResponder
- 单击并编辑规则以:
Add Rule
- 方法:OPTIONS服务器url,例如
Method:OPTIONS http://localhost
*CORSPreflightAllow
- 方法:OPTIONS服务器url,例如
- 检查
Unmatched requests passthrough
- 检查
Enable Rules
几点说明:
- 显然,这只是一个用于开发/测试的解决方案,其中无法/实际修改 API 服务
- 检查您与第三方 API 提供商签订的任何协议是否允许您执行此操作
- 正如其他人所指出的,这是 CORS 工作方式的一部分,最终需要在 API 服务器上设置标头。如果控制该服务器,则可以自行设置标头。在这种情况下,由于它是第三方服务,我只能假设他们有某种机制,您可以通过该机制向他们提供原始站点的 URL,并且他们会相应地更新他们的服务以响应正确的标题。
您是否尝试过将 AJAX 请求中的 从 更改为 ?这在我的情况下解决了它。dataType
jsonp
json
dataType:'jsonp',
您正在发出 JSONP 请求,但服务器正在使用 JSON 进行响应。
浏览器拒绝尝试将 JSON 视为 JSONP,因为这会带来安全风险。(如果浏览器确实尝试将 JSON 视为 JSONP,那么它充其量只会失败)。
有关JSONP是什么的更多详细信息,请参阅此问题。请注意,这是一个令人讨厌的黑客,可以绕过在 CORS 可用之前使用的同源策略。CORS 是一种更清洁、更安全、更强大的解决方案。
看起来您正在尝试提出跨域请求,并将您能想到的所有内容都扔在一大堆相互冲突的指令中。
您需要了解同源策略的工作原理。
有关深入指南,请参阅此问题。
现在,关于代码的一些说明:
contentType: 'application/json',
- 使用 JSONP 时,将忽略此值
- 您正在发出 GET 请求。没有请求正文来描述类型。
- 这将使跨域请求变得不简单,这意味着除了基本的 CORS 权限外,您还需要处理预检。
删除它。
dataType:'jsonp',
- 服务器未使用 JSONP 进行响应。
删除它。(您可以让服务器改用 JSONP 进行响应,但 CORS 更好)。
responseType:'application/json',
jQuery.ajax 不支持此选项。删除它。
xhr字段:{ withCredentials: false },
这是默认设置。除非您使用 ajaxSetup 将其设置为 true,否则请将其删除。
headers: { 'Access-Control-Allow-Credentials' : true, 'Access-Control-Allow-Origin':'*', 'Access-Control-Allow-Methods':'GET', 'Access-Control-Allow-Headers':'application/json', },
- 这些是响应标头。它们属于响应,而不是请求。
- 这将使跨域请求变得不简单,这意味着除了基本的 CORS 权限外,您还需要处理预检。
返回标头为“Access-Control-Allow-Origin:*”的响应 检查下面的代码以获取 Php 服务器响应。
<?php header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json');
echo json_encode($phparray);
评论
Content-Type: application/json
如果你在localhost上工作,试试这个,这是唯一对我有用的扩展和方法(Angular,只有javascript,没有php)
我遇到了这个问题,因为来自服务器的jsonp响应的格式是错误的。不正确的响应如下。
callback(["apple", "peach"])
问题是,里面的对象应该是一个正确的 json 对象,而不是一个 json 数组。所以我修改了一些服务器代码并更改了其格式:callback
callback({"fruit": ["apple", "peach"]})
修改后,浏览器愉快地接受了响应。
评论
callback(["apple", "peach"])
是完全有效的 JSONP,并且在我跨源测试时工作正常。
在这种情况下,有一个值得一提的边缘情况:Chrome(至少某些版本)使用为 CORB 设置的算法检查 CORS 预检。IMO,这有点愚蠢,因为预检似乎不会影响 CORB 威胁模型,而 CORB 似乎被设计为与 CORS 正交。此外,CORS 预检的主体是不可访问的,因此没有负面后果,只是一个令人恼火的警告。
无论如何,请检查 CORS 预检响应(OPTIONS 方法响应)是否没有正文 (204)。内容类型为 application/octet-stream 且长度为零的空 200 在这里也运行良好。
您可以通过使用消息正文计算 CORB 警告与 OPTIONS 响应来确认是否遇到这种情况。
如果您在谷歌浏览器中遇到问题,请尝试安装“Moesif CORS”扩展程序。由于它是跨域请求,因此即使响应状态代码为 200,chrome 也不会接受响应
评论
我的 Chrome 扩展程序也遇到了同样的问题。当我尝试将这部分添加到我的清单“content_scripts”选项时:
//{
// "matches": [ "<all_urls>" ],
// "css": [ "myStyles.css" ],
// "js": [ "test.js" ]
//}
我从我的清单“permissons”中删除了另一部分:
"https://*/"
只有当我在我的 XHR 要求之一上删除它时。
最糟糕的是,我的代码中很少有 XHR 请求,只有一个开始出现 CORB 错误(为什么 CORB 不应用其他 XHR 我不知道;为什么清单更改与此错误同时出现我不知道)。这就是为什么我花了几个小时一遍又一遍地检查整个代码并浪费了很多时间。
评论
似乎在发送带有 200 的空响应时发生了此警告。
我的这个配置在Chrome上显示警告:.htaccess
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST,GET,HEAD,OPTIONS,PUT,DELETE"
Header always set Access-Control-Allow-Headers "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization"
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule .* / [R=200,L]
但是将最后一行更改为
RewriteRule .* / [R=204,L]
解决问题!
在 Chrome 扩展程序中,您可以使用
chrome.webRequest.onHeadersReceived.addListener
重写服务器响应标头。您可以替换现有标头,也可以添加其他标头。这是您想要的标头:
Access-Control-Allow-Origin: *
https://developers.chrome.com/extensions/webRequest#event-onHeadersReceived
我被困在 CORB 问题上,这为我解决了它。
评论
我也有类似的问题。我的情况是因为服务器响应的 contentType 是 application/json,而不是 text/javascript。
所以,我从我的服务器(spring mvc)解决它:
// http://127.0.0.1:8080/jsonp/test?callback=json_123456
@GetMapping(value = "/test")
public void testJsonp(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
@RequestParam(value = "callback", required = false) String callback) throws IOException {
JSONObject json = new JSONObject();
json.put("a", 1);
json.put("b", "test");
String dataString = json.toJSONString();
if (StringUtils.isBlank(callback)) {
httpServletResponse.setContentType("application/json; charset=UTF-8");
httpServletResponse.getWriter().print(dataString);
} else {
// important: contentType must be text/javascript
httpServletResponse.setContentType("text/javascript; charset=UTF-8");
dataString = callback + "(" + dataString + ")";
httpServletResponse.getWriter().print(dataString);
}
}
评论