跨域读取阻塞 (CORB)

Cross-Origin Read Blocking (CORB)

提问人:Jignesh 提问时间:6/15/2018 最后编辑:sideshowbarkerJignesh 更新时间:12/13/2022 访问量:555394

问:

我已经使用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 成功方法中。

请帮帮我。

javascript jquery ajax cors 跨域读取阻塞

评论

4赞 Rory McCrossan 6/15/2018
您调用的 API 似乎尚未启用允许来自 JS 的跨域调用所需的标头。您很可能需要在服务器上进行调用。您确定响应是 JSONP 而不是普通 JSON 吗?另请注意,在请求中添加的标头需要改为放置在服务器的响应中。
4赞 Sherwin Ablaña Dapito 8/21/2018
您是否解决了此 CORB 错误或警告?我在请求模块中遇到了同样的情况。
5赞 Colin Young 9/25/2018
@SherwinAblañaDapito,如果您仍在寻找解决方案,请参阅我对开发/测试环境的回答
1赞 Ruslan Novikov 9/29/2018
为了演示您的 JS 如何正常工作,您可以在不安全的模式下启动 Chrome chrome.exe --user-data-dir=“C:/Chrome dev session” --disable-web-security 但是必须在服务器端修复“读取阻止 (CORB) 阻止跨域响应”。

答:

-1赞 lifetimeLearner007 6/15/2018 #1

响应标头通常在服务器上设置。设置为在服务器端'Access-Control-Allow-Headers''Content-Type'

评论

8赞 Jignesh 6/17/2018
我正在使用第三方 API。所以我不能那样做。请给我任何客户端解决方案。
4赞 lifetimeLearner007 6/17/2018
服务器决定允许什么,不允许什么。只有服务器具有该访问权限。从客户端控制响应标头存在安全风险。客户端的工作是发送正确的请求,然后获取服务器发送的任何响应。看这个:stackoverflow.com/questions/17989951/...
56赞 Joaquin Brandan 8/16/2018
这是 CORB,而不是 CORS。
1赞 mydoglixu 12/12/2021
我一直在寻找 CORB 帮助 - 这解决了它 - 谢谢!!
8赞 Shubham Verma 6/27/2018 #2

您必须在服务器端添加 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);

评论

28赞 Alexander Falk 7/23/2018
如果需要添加扩展来解决问题,则错误地在服务器端处理请求。只是一个笔记。
3赞 Izzy Rodriguez 7/30/2018
要求我的用户群安装一个奇怪的 Chrome 扩展程序是不可行的。其他浏览器呢?
2赞 KoldBane 8/30/2018
虽然这个答案并不能长期解决问题,但正是使用这个插件向我的同事验证了这是一个 CORS 问题。所以为此投了赞成票!
2赞 Izzy Rodriguez 2/2/2019
@VladimirNul最初的答案是关于 chrome 扩展程序的。Shubham 重写了它。请检查历史记录。
4赞 Not a machine 3/9/2019
这里有一些混乱。OP 指的是 CORB 而不是 CORS。
21赞 Marcelo 7/3/2018 #3

在大多数情况下,被阻止的响应不应影响网页的行为,并且可以安全地忽略 CORB 错误消息。例如,当被阻止的响应的正文已为空时,或者当响应将传递到无法处理它的上下文(例如,将 HTML 文档(如 404 错误页面)传递到标记)时,可能会出现警告。

https://www.chromium.org/Home/chromium-security/corb-for-developers

我必须清理浏览器的缓存,我在此链接中阅读,如果请求得到空响应,我们会收到此警告错误。我在我的请求中得到了一些 CORS,所以这个请求的响应是空的,我所要做的就是清除浏览器的缓存,然后 CORS 就消失了。我收到 CORS,因为 chrome 已将 PORT 号保存在缓存中,服务器只会接受,而我正在这样做,因为缓存。localhost:3010localhost:3002

3赞 Colin Young 9/25/2018 #4

从问题中尚不清楚,但假设这是在开发或测试客户端上发生的事情,并且鉴于你已在使用 Fiddler,你可以让 Fiddler 使用允许响应进行响应:

  • 在 Fiddler 中选择问题请求
  • 打开选项卡AutoResponder
  • 单击并编辑规则以:Add Rule
    • 方法:OPTIONS服务器url,例如Method:OPTIONS http://localhost
    • *CORSPreflightAllow
  • 检查Unmatched requests passthrough
  • 检查Enable Rules

几点说明:

  1. 显然,这只是一个用于开发/测试的解决方案,其中无法/实际修改 API 服务
  2. 检查您与第三方 API 提供商签订的任何协议是否允许您执行此操作
  3. 正如其他人所指出的,这是 CORS 工作方式的一部分,最终需要在 API 服务器上设置标头。如果控制该服务器,则可以自行设置标头。在这种情况下,由于它是第三方服务,我只能假设他们有某种机制,您可以通过该机制向他们提供原始站点的 URL,并且他们会相应地更新他们的服务以响应正确的标题。
2赞 Cla 10/29/2018 #5

您是否尝试过将 AJAX 请求中的 从 更改为 ?这在我的情况下解决了它。dataTypejsonpjson

57赞 Quentin 2/12/2019 #6
 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 权限外,您还需要处理预检。
14赞 Jestin 2/19/2019 #7

返回标头为“Access-Control-Allow-Origin:*”的响应 检查下面的代码以获取 Php 服务器响应。

<?php header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json');
echo json_encode($phparray); 

评论

3赞 Adam Laurie 6/16/2019
你的回答对我帮助很大!!我简直感激不尽。我将继续研究“访问控制允许源”的作用,因此我了解其后果,但我只是在学习创建PHP Web服务的基础知识,这对我有帮助,就像你不会相信的那样。谢谢!!!
0赞 Quentin 6/24/2019
这根本无法解决问题。这是由发送响应引起的 CORB 错误。OP 的代码必须已经在执行此操作。Content-Type: application/json
1赞 Pacerier 6/12/2020
@Quentin,???常识指出,只要您有 Allow Origin,浏览器就会允许请求,而不管是否有任何可疑的标头/正文。
0赞 Quentin 6/23/2022
@Pacerier — 常识和 CORB 错误消息说,如果您尝试像执行 JavaScript 一样执行 JSON 文件,那么它将失败。
3赞 pmiranda 6/3/2019 #8

如果你在localhost上工作,试试这个,这是唯一对我有用的扩展和方法(Angular,只有javascript,没有php)

https://chrome.google.com/webstore/detail/moesif-orign-cors-changer/digfbfaphojjndkpccljibejjbppifbc/related?hl=en

-4赞 Searene 6/24/2019 #9

我遇到了这个问题,因为来自服务器的jsonp响应的格式是错误的。不正确的响应如下。

callback(["apple", "peach"])

问题是,里面的对象应该是一个正确的 json 对象,而不是一个 json 数组。所以我修改了一些服务器代码并更改了其格式:callback

callback({"fruit": ["apple", "peach"]})

修改后,浏览器愉快地接受了响应。

评论

0赞 Quentin 6/24/2019
callback(["apple", "peach"])是完全有效的 JSONP,并且在我跨源测试时工作正常。
2赞 Simon Thum 6/30/2019 #10

在这种情况下,有一个值得一提的边缘情况:Chrome(至少某些版本)使用为 CORB 设置的算法检查 CORS 预检。IMO,这有点愚蠢,因为预检似乎不会影响 CORB 威胁模型,而 CORB 似乎被设计为与 CORS 正交。此外,CORS 预检的主体是不可访问的,因此没有负面后果,只是一个令人恼火的警告。

无论如何,请检查 CORS 预检响应(OPTIONS 方法响应)是否没有正文 (204)。内容类型为 application/octet-stream 且长度为零的空 200 在这里也运行良好。

您可以通过使用消息正文计算 CORB 警告与 OPTIONS 响应来确认是否遇到这种情况。

-4赞 Madhurish Gupta 7/2/2019 #11

如果您在谷歌浏览器中遇到问题,请尝试安装“Moesif CORS”扩展程序。由于它是跨域请求,因此即使响应状态代码为 200,chrome 也不会接受响应

评论

0赞 pointysticks45 5/6/2021
这是个坏建议。您不想告诉用户安装扩展程序来访问您的网站。
-2赞 Олег Хитрень 7/7/2019 #12

我的 Chrome 扩展程序也遇到了同样的问题。当我尝试将这部分添加到我的清单“content_scripts”选项时:

//{
    //  "matches": [ "<all_urls>" ],
    //  "css": [ "myStyles.css" ],
    //  "js": [ "test.js" ]
    //}

我从我的清单“permissons”中删除了另一部分:

"https://*/"

只有当我在我的 XHR 要求之一上删除它时。

最糟糕的是,我的代码中很少有 XHR 请求,只有一个开始出现 CORB 错误(为什么 CORB 不应用其他 XHR 我不知道;为什么清单更改与此错误同时出现我不知道)。这就是为什么我花了几个小时一遍又一遍地检查整个代码并浪费了很多时间。

评论

0赞 Олег Хитрень 7/7/2019
服务器端的标头存在一些问题。我将 ASP.NET 返回值更改为: public async Task<string> Get(string TM) 返回值是刚才的JSON(我猜是“application/json”的内容类型),现在是另一个(可能是“text/plain”)。这很有帮助。现在我将清单“权限”返回到“https://*/”并且它可以工作。
1赞 fluminis 10/1/2019 #13

似乎在发送带有 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]

解决问题!

3赞 stepper 11/18/2019 #14

在 Chrome 扩展程序中,您可以使用

chrome.webRequest.onHeadersReceived.addListener

重写服务器响应标头。您可以替换现有标头,也可以添加其他标头。这是您想要的标头:

Access-Control-Allow-Origin: *

https://developers.chrome.com/extensions/webRequest#event-onHeadersReceived

我被困在 CORB 问题上,这为我解决了它。

评论

2赞 swisswiss 4/5/2020
“从 Chrome 72 开始,如果需要在跨域读取阻止 (CORB) 阻止响应之前修改响应,则需要在 opt_extraInfpSpec 中指定'extraHeaders'。”
0赞 learner 3/5/2021 #15

我也有类似的问题。我的情况是因为服务器响应的 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);
        }
    }