Блокировка чтения из разных источников (CORB)

130

Я вызвал сторонний API с помощью JQuery AJAX. В консоли появляется следующая ошибка:

Блокировка чтения из разных источников (CORB) заблокировала ответ из разных источников. МОЙ URL с типом MIME application / json. См. 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.

Пожалуйста, помогите мне.

Jignesh
источник
3
Похоже, что вызываемый вами API не включил заголовки, необходимые для разрешения междоменных вызовов из JS. Скорее всего, вам придется вместо этого позвонить на сервер. Вы уверены, что ответ - это JSONP, а не простой JSON? Также обратите внимание, что заголовки, которые вы добавляете в запрос, должны быть размещены в ответе сервера.
Рори МакКроссан
3
Вы устранили эту ошибку или предупреждение CORB? Я испытываю то же самое с модулем запроса.
Шервин Абланья Дапито
3
@ SherwinAblañaDapito, если вы все еще ищете решение, см. Мой ответ по средам разработки / тестирования
Колин Янг,
1
Чтобы продемонстрировать, как ваш JS может работать правильно, вы можете запустить Chrome в небезопасном режиме chrome.exe --user-data-dir = "C: / Chrome dev session" --disable-web-security But "Read Blocking (CORB) заблокированный ответ между источниками " должен быть исправлен на стороне сервера.
Руслан Новиков

Ответы:

37
 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. Удали это.

xhrFields: {withCredentials: false},

Это значение по умолчанию. Если вы не устанавливаете для него значение true с помощью ajaxSetup, удалите это.

  headers: {
    'Access-Control-Allow-Credentials' : true,
    'Access-Control-Allow-Origin':'*',
    'Access-Control-Allow-Methods':'GET',
    'Access-Control-Allow-Headers':'application/json',
  },
  • Это заголовки ответа. Они принадлежат ответу, а не запросу.
  • Это сделает запрос между источниками непростым, а это означает, что помимо основных разрешений CORS вам также необходимо иметь дело с предполетным.
Quentin
источник
20

В большинстве случаев заблокированный ответ не должен влиять на поведение веб-страницы, и сообщение об ошибке CORB можно безопасно игнорировать. Например, предупреждение может появиться в тех случаях, когда тело заблокированного ответа уже было пустым или когда ответ должен был быть доставлен в контекст, который не может его обработать (например, документ HTML, такой как страница с ошибкой 404 доставляется в тег).

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

Мне пришлось очистить кеш своего браузера, я читал по этой ссылке, что, если запрос получит пустой ответ, мы получим это предупреждение об ошибке. Я получал CORS по моему запросу, и поэтому ответ на этот запрос стал пустым. Все, что мне нужно было сделать, это очистить кеш браузера, и CORS ушел. Я получал CORS, потому что хром сохранил номер ПОРТА в кеше, сервер просто согласился, localhost:3010и я делал это localhost:3002из-за кеша.

Alex
источник
12

Вернуть ответ с заголовком «Access-Control-Allow-Origin: *». Проверьте код ниже для ответа сервера Php.

<?php header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json');
echo json_encode($phparray); 
Jestin
источник
2
Ваш ответ НАСТОЛЬКО мне помог !!! Я просто не могу вас отблагодарить. Я буду продолжать исследовать, что делает «Access Control Allow Origin», чтобы понять последствия, но я только изучаю основы создания веб-службы PHP, и это помогло мне, как вы не поверите. СПАСИБО!!!
Адам Лори
Это вообще не решает проблему. Это ошибка CORB, вызванная отправкой в ​​ней ответа Content-Type: application/json. Код OP уже должен это делать.
Quentin
1
@ Квентин, ??? Здравый смысл гласит, что пока у вас есть Allow Origin, браузер будет разрешать запрос независимо от любого подозрительного заголовка / тела.
Pacerier
7

Вам необходимо добавить 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);
Шубхам Верма
источник
22
Если вам нужно добавить расширение для решения вашей проблемы, вы неправильно обрабатываете запрос на стороне сервера. Просто примечание.
Александр Фальк
2
Невозможно просить мою пользовательскую базу установить странное расширение Chrome. А как насчет других браузеров?
Israel Rodriguez
2
Хотя этот ответ не решает проблему в долгосрочной перспективе, он использовал этот плагин, который подтвердил моим коллегам, что это проблема CORS. Так что за это проголосовали!
KoldBane
2
@VladimirNul исходный ответ был о расширении Chrome. Шубхам его переписал. Пожалуйста, проверьте историю.
Israel Rodriguez
3
Здесь есть некоторая путаница. OP относится к CORB, а не к CORS.
Не машина
3

Это не ясно из вопроса, но при условии, что это что-то происходит на клиенте разработки или тестирования, и учитывая, что вы уже используете Fiddler, вы можете получить ответ Fiddler разрешающим ответом:

  • Выберите проблемный запрос в Fiddler
  • Откройте AutoResponderвкладку
  • Щелкните Add Ruleи измените правило, чтобы:
    • Метод: здесь URL-адрес сервера OPTIONS , напримерMethod:OPTIONS http://localhost
    • *CORSPreflightAllow
  • Проверьте Unmatched requests passthrough
  • Проверьте Enable Rules

Пара заметок:

  1. Очевидно, что это только решение для разработки / тестирования, когда невозможно / нецелесообразно изменять службу API.
  2. Убедитесь, что любые соглашения, заключенные у вас со сторонним поставщиком API, позволяют это делать.
  3. Как отмечали другие, это часть того, как работает CORS, и в конечном итоге заголовок необходимо будет установить на сервере API. Если вы контролируете этот сервер, вы можете установить заголовки самостоятельно. В этом случае, поскольку это сторонняя служба, я могу только предположить, что у них есть какой-то механизм, с помощью которого вы можете предоставить им URL-адрес исходного сайта, и они соответственно обновят свою службу, чтобы ответить с правильными заголовками.
Колин Янг
источник
2

вы пробовали изменить dataTypeв своем запросе ajax с jsonpна json? это исправило это в моем случае.

Cla
источник
2

В расширении Chrome вы можете использовать

chrome.webRequest.onHeadersReceived.addListener

переписать заголовки ответа сервера. Вы можете заменить существующий заголовок или добавить дополнительный заголовок. Это тот заголовок, который вам нужен:

Access-Control-Allow-Origin: *

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

Я застрял на проблемах CORB, и это решило для меня.

шаговый
источник
1
«Начиная с Chrome 72, если вам нужно изменить ответы до того, как блокировка чтения перекрестных источников (CORB) сможет заблокировать ответ, вам нужно указать 'extraHeaders' в opt_extraInfpSpec». из webRequests doc
swisswiss
0

Заголовки ответа обычно устанавливаются на сервере. Установите 'Access-Control-Allow-Headers'на 'Content-Type'на стороне сервера

lifetimeLearner007
источник
7
Я использую сторонний API. Так что я не могу этого сделать. Пожалуйста, дайте мне любое решение на стороне клиента.
Jignesh
4
Сервер решает, что разрешить, а что нет. Только сервер имеет такой доступ. Управление заголовками ответов со стороны клиента представляет угрозу безопасности. Задача клиентской стороны - отправить правильный запрос, а затем получить ответ, отправленный сервером. Смотрите это: stackoverflow.com/questions/17989951/...
lifetimeLearner007
48
Это CORB, а не CORS.
Хоакин Брандан
0

Блокировка чтения из разных источников (CORB), алгоритм, с помощью которого веб-браузеры могут идентифицировать и блокировать загрузку ресурсов из разных источников до того, как они достигнут веб-страницы. Он предназначен для предотвращения доставки браузером определенных сетевых ответов из разных источников. на веб-страницу.

Сначала убедитесь, что эти ресурсы обслуживаются с правильным " Content-Type", т. Е. Для типа MIME JSON - " text/json", " application/json", типа MIME HTML - " text/html".

Во-вторых: установите режим на cors, т.е. mode:cors

Получение будет выглядеть примерно так

 fetch("https://example.com/api/request", {
            method: 'POST',
            body: JSON.stringify(data),
            mode: 'cors',
            headers: {
                'Content-Type': 'application/json',
                "Accept": 'application/json',
            }
        })
    .then((data) => data.json())
    .then((resp) => console.log(resp))
    .catch((err) => console.log(err))

ссылки: https://chromium.googlesource.com/chromium/src/+/master/services/network/cross_origin_read_blocking_explainer.md

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

Никил Муниредди
источник
0

В этом контексте стоит упомянуть крайний случай: Chrome (по крайней мере, в некоторых версиях) проверяет предварительные рейсы CORS, используя алгоритм, настроенный для CORB . ИМО, это немного глупо, потому что предполетные операции, похоже, не влияют на модель угроз CORB, а CORB, похоже, разработан ортогонально CORS. Кроме того, тело предварительной проверки CORS недоступно, поэтому нет никаких негативных последствий, только раздражающее предупреждение.

В любом случае убедитесь, что ваши предварительные ответы CORS (ответы метода OPTIONS) не имеют тела (204) . Пустой 200 с типом содержимого application / octet-stream и нулевой длиной здесь тоже хорошо работал.

Вы можете подтвердить, действительно ли это так, посчитав предупреждения CORB и ответы OPTIONS с телом сообщения.

Саймон Тум
источник
0

Похоже, это предупреждение возникло при отправке пустого ответа с 200.

Эта конфигурация в моем .htaccessотображении предупреждения в Chrome:

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]

решить вопрос!

fluminis
источник
-2

У меня была такая же проблема с расширением Chrome. Когда я попытался добавить в свой манифест опцию content_scripts эту часть:

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

А другую часть я удаляю из манифеста "разрешений":

"https://*/"

Только когда я удаляю его CORB в одном из моих запросов XHR, разочаровывается.

Хуже всего то, что в моем коде мало запросов XHR, и только один из них начинает получать ошибку CORB (почему CORB не отображается на другом XHR, я не знаю; почему явные изменения вызвали эту ошибку, я не знаю). Вот почему я проверял весь код снова и снова через несколько часов и потерял много времени.

Олег Хитрень
источник
На стороне сервера возникла проблема с заголовками. Я меняю свое возвращаемое значение ASP.NET на: public async Task <string> Get (string TM) Возвращаемое значение было мгновение назад JSON (тип содержимого, я думаю, «application / json»), а теперь это другой (может быть «текст» / обычный "). И это помогает. Теперь я возвращаю манифест «разрешения» на «https: // * /», и он работает.
Олег Хитрень 07
-3

Если вы делаете это в сафари, это не займет много времени. Просто включите меню разработчика в разделе «Настройки» >> «Конфиденциальность» и снимите флажок «Отключить ограничения для разных источников» в меню разработки. Если вы хотите только локальный, вам нужно только включить меню разработчика и выбрать «Отключить локальные ограничения файлов» в меню разработки.

а в Chrome для OSX откройте Терминал и запустите:

$ open -a Google\ Chrome --args --disable-web-security --user-data-dir

--user-data-dir требуется в Chrome 49+ на OSX

Для запуска Linux:

$ google-chrome --disable-web-security

Также, если вы пытаетесь получить доступ к локальным файлам для целей разработки, таких как AJAX или JSON, вы также можете использовать этот флаг.

-–allow-file-access-from-files

Для Windows войдите в командную строку, перейдите в папку, где находится Chrome.exe, и введите

chrome.exe --disable-web-security

Это должно отключить ту же политику происхождения и позволить вам получить доступ к локальным файлам.

Мухаммад Харис Баиг
источник
-3

Я столкнулся с этой проблемой, потому что формат ответа jsonp от сервера неправильный. Неправильный ответ выглядит следующим образом.

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

Проблема в том, что объект внутри callbackдолжен быть правильным объектом json, а не массивом json. Поэтому я изменил код сервера и изменил его формат:

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

Браузер с радостью принял ответ после модификации.

Searene
источник
callback(["apple", "peach"])является совершенно допустимым JSONP и отлично работал, когда я тестировал его в разных источниках.
Quentin
-4

Попробуйте установить расширение «Moesif CORS», если вы столкнулись с проблемой в Google Chrome. Поскольку это запрос с перекрестным происхождением, хром не принимает ответ, даже если код состояния ответа равен 200

Мадхуриш Гупта
источник