it-swarm.com.ru

Почему мой JavaScript получает сообщение об ошибке "Отсутствует заголовок Access-Control-Allow-Origin" на запрошенном ресурсе ", а Postman - нет?

Я пытаюсь выполнить авторизацию, используя JavaScript , подключившись к RESTfulAPI встроенному Flask . Однако, когда я делаю запрос, я получаю следующую ошибку:

XMLHttpRequest не может загрузить http: // myApiUrl/login . В запрошенном ресурсе отсутствует заголовок «Access-Control-Allow-Origin». Происхождение 'null', следовательно, не разрешено.

Я знаю, что API или удаленный ресурс должен устанавливать заголовок, но почему он работал, когда я делал запрос через расширение Chrome Почтальон ?

Это код запроса:

$.ajax({
    type: "POST",
    dataType: 'text',
    url: api,
    username: 'user',
    password: 'pass',
    crossDomain : true,
    xhrFields: {
        withCredentials: true
    }
})
    .done(function( data ) {
        console.log("done");
    })
    .fail( function(xhr, textStatus, errorThrown) {
        alert(xhr.responseText);
        alert(textStatus);
    });
2059
Mr Jedi

Если я правильно понял, вы делаете XMLHttpRequest в другой домен, чем ваша страница. Таким образом, браузер блокирует его, поскольку он обычно позволяет запрос в том же источнике по соображениям безопасности. Вам нужно сделать что-то другое, когда вы хотите сделать междоменный запрос. Учебник о том, как этого достичь, Использование CORS.

Когда вы используете почтальон, они не ограничены этой политикой. Цитируется из XMLHttpRequest перекрестного происхождения:

Обычные веб-страницы могут использовать объект XMLHttpRequest для отправки и получения данных с удаленных серверов, но они ограничены одной и той же политикой Origin. Расширения не так ограничены. Расширение может общаться с удаленными серверами за пределами своего источника, если оно сначала запрашивает разрешения между источниками.

1124
MD. Sahib Bin Mahboob

Это не исправление для производства или когда приложение должно быть показано клиенту, это полезно только тогда, когда пользовательский интерфейс и Backend development находятся на разных server, а в производстве они фактически находятся на одном сервере. Например: при разработке пользовательского интерфейса для любого приложения, если необходимо проверить его локально, направив его на внутренний сервер, в этом сценарии это идеальное решение. Для производственного исправления заголовки CORS должны быть добавлены на внутренний сервер, чтобы разрешить перекрестный доступ к источникам.

Самый простой способ - просто добавить расширение в Google Chrome, чтобы разрешить доступ с помощью CORS.

( https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en-US )

Просто включите это расширение всякий раз, когда вы хотите разрешить доступ к запросу без заголовка 'access-control-allow-Origin'.

Или же 

В Windows вставьте эту команду в окно run 

chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security

это откроет новый браузер chrome, который разрешит доступ к запросу без заголовка 'access-control-allow-Origin'.

485
shruti

Если вы можете иметь дело с JSON взамен, попробуйте использовать JSONP (обратите внимание на P в конце) для разговора между доменами:

$.ajax({
  type: "POST",
  dataType: 'jsonp',
  ...... etc ......

Узнайте больше о работе с JSONP здесь :

Появление JSONP - по сути согласованного хакерского сценария - открыло двери для мощных коллажей контента. Многие известные сайты предоставляют сервисы JSONP, позволяющие вам получить доступ к их контенту через предопределенный API.

322
Gavin

Это очень просто решить, если вы используете PHP . Просто добавьте следующий скрипт в начало страницы PHP, которая обрабатывает запрос:

<?php header('Access-Control-Allow-Origin: *'); ?>

Предупреждение: Это содержит проблему безопасности для вашего файла PHP, которую он может вызвать злоумышленники. Вы должны использовать сеансы и куки для аутентификации, чтобы предотвратить ваш файл/сервис от этой атаки. Ваш сервис уязвим для подделка межсайтовых запросов (CSRF).

Если вы используете Node-red вы должны разрешить CORS в файле node-red/settings.js, не комментируя следующие строки:

// The following property can be used to configure cross-Origin resource sharing
// in the HTTP nodes.
// See https://github.com/troygoode/node-cors#configuration-options for
// details on its contents. The following is a basic permissive set of options:
httpNodeCors: {
 Origin: "*",
 methods: "GET,PUT,POST,DELETE"
},
200
shady sherif

Я хотел бы, чтобы кто-то давно поделился этим сайтом со мной http://cors.io/ это сэкономило бы кучу времени по сравнению с созданием и использованием моего собственного прокси-сервера. Однако, когда вы переходите на работу, лучше всего иметь собственный прокси, поскольку вы все еще контролируете все аспекты своих данных.

Все, что тебе нужно:

https://cors.io/?http://HTTP_YOUR_LINK_HERE

168
yoshyosh

Если вы используете Node.js , попробуйте:

app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
});

Дополнительная информация: CORS на ExpressJS

67
Nguyen Tran

Существует междоменная проблема с использованием Ajax. Вы должны быть уверены, что обращаетесь к своим файлам по тому же пути http:// без www. (или обращаетесь к http://www. и отправляете по тому же пути, включая www.), который браузер рассматривает как другой домен при доступе по пути www., поэтому вы видите, где проблема является. Вы отправляете сообщение в другой домен, и браузер блокирует поток из-за проблемы с источником.

Если API не находится на том же хосте, с которого вы запрашиваете, поток блокируется, и вам нужно будет найти другой способ связи с API.

63
Alin Razvan

Так как 
$ .ajax ({type: "POST" - вызовы ПАРАМЕТРОВ 
$ .post ( - Звонки POST 

оба разных почтальона правильно называют «POST», но когда мы будем звонить, это будет «OPTIONS»

Для веб-сервисов c # - webapi 

Добавьте следующий код в файл web.config под тегом <system.webServer>. Это будет работать

<httpProtocol>
    <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
    </customHeaders>
</httpProtocol>

Пожалуйста, убедитесь, что вы не делаете никаких ошибок в вызове ajax

jQuery

$.ajax({
    url: 'http://mysite.Microsoft.sample.xyz.com/api/mycall',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    type: "POST", /* or type:"GET" or type:"PUT" */
    dataType: "json",
    data: {
    },
    success: function (result) {
        console.log(result);    
    },
    error: function () {
        console.log("error");
    }
});

Выпуск Angular 4, пожалуйста, обратитесь: http://www.hubfly.com/blog/solutions/how-to-fix-angular-4-api-call-issues/

Примечание: Если вы ищете для загрузки контента со стороннего веб-сайта, то это вам не поможет. Вы можете попробовать следующий код, но не JavaScript.

System.Net.WebClient wc = new System.Net.WebClient();
string str = wc.DownloadString("http://mysite.Microsoft.sample.xyz.com/api/mycall");
48
George Livingston

Попробуйте XDomain ,

Описание: чистая альтернатива JavaScript CORS/polyfill. Не требуется настройка сервера - просто добавьте proxy.html в домен, с которым вы хотите общаться. Эта библиотека использует XHook для перехвата всех XHR , поэтому XDomain должен работать совместно с любой библиотекой.

22
user3359786

Если вы не хотите, чтобы:

  1. Отключить веб-безопасность в Chrome
  2. Используйте JSONP
  3. Используйте сторонний сайт для перенаправления ваших запросов

и вы уверены, что на вашем сервере включена поддержка CORS (протестируйте CORS здесь: http://www.test-cors.org/ )

Затем вам нужно передать параметр Origin с вашим запросом . Этот Origin ДОЛЖЕН совпадать с источником, который ваш браузер отправляет с вашим запросом.

Вы можете увидеть это в действии здесь: http://www.wikinomad.com/app/detail/Campgrounds/3591

Функция редактирования отправляет запрос GET & POST в другой домен для извлечения данных. Я установил параметр Origin, который решает проблему . Бэкэнд - это движок mediaWiki.

tldr: добавьте параметр «Origin» к вашим вызовам, который должен быть параметром Origin, который отправляет ваш браузер (вы не можете подделать параметр Origin)

11
Ganesh Krishnan

У меня была проблема с этим, когда я использовал AngularJS для доступа к своему API. Тот же запрос работал в SoapUI 5.0 и ColdFusion. Мой метод GET уже имел заголовок Access-Control-Allow-Origin.

Я обнаружил, что AngularJS делает «пробный» запрос ОПЦИИ . ColdFusion по умолчанию генерирует метод OPTIONS, но у него не так много, особенно эти заголовки. Ошибка была сгенерирована в ответ на этот вызов OPTIONS, а не на мой преднамеренный вызов GET. После того, как я добавил метод OPTIONS ниже в мой API, проблема была решена.

<cffunction name="optionsMethod" access="remote" output="false" returntype="any" httpmethod="OPTIONS" description="Method to respond to AngularJS trial call">
    <cfheader name="Access-Control-Allow-Headers" value="Content-Type,x-requested-with,Authorization,Access-Control-Allow-Origin"> 
    <cfheader name="Access-Control-Allow-Methods" value="GET,OPTIONS">      
    <cfheader name="Access-Control-Allow-Origin" value="*">      
    <cfheader name="Access-Control-Max-Age" value="360">        
</cffunction>
8
Leonid Alzhin

У меня была следующая конфигурация, приводившая к той же ошибке при запросе ответов от сервера.

На стороне сервера:SparkJava -> предоставляет REST-API
Клиентская сторона:ExtJs6 -> обеспечивает рендеринг в браузере 

На серверной стороне мне пришлось добавить это в ответ: 

Spark.get("/someRestCallToSpark", (req, res) -> {
    res.header("Access-Control-Allow-Origin", "*"); //important, otherwise its not working 
    return "some text";
 });

На клиентской стороне мне пришлось добавить это к запросу: 

Ext.Ajax.request({
    url: "http://localhost:4567/someRestCallToSpark",
    useDefaultXhrHeader: false, //important, otherwise its not working
    success: function(response, opts) {console.log("success")},
    failure: function(response, opts) {console.log("failure")}
});
8
kiltek

Основываясь на ответе shruti , я создал ярлык браузера Chrome с необходимыми аргументами: enter image description here enter image description here

8
Mohammad AlBanna

https://github.com/Rob--W/cors-anywhere/ предоставляет (Node.js) код, который можно использовать для настройки и запуска собственного прокси-сервера CORS. Он активно поддерживается и предоставляет ряд функций для управления поведением прокси-сервера, помимо базовой отправки правильных заголовков ответа Access-Control-*.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS содержит подробные сведения, объясняющие, как браузеры обрабатывают запросы из разных источников, которые клиентские веб-приложения делают из JavaScript, и какие заголовки необходимо если возможно, настройте отправку сервером запроса.

В случае, когда сайт, на который вам нужно сделать запрос и получить ответ, не возвращает заголовок ответа Access-Control-Allow-Origin, браузеры всегда собираются блокировать запросы к другим источникам, сделанные ему напрямую вашей клиентской стороной. Код JavaScript с работы. И поэтому, если сайт не тот, которым вы управляете и для которого можете настроить поведение, единственное, что будет работать в этом случае, - это проксирование запросов - либо через собственный прокси-сервер, который вы запускаете самостоятельно, либо через открытый прокси-сервер.

Как уже упоминалось в других комментариях здесь, есть веские причины не доверять открытому прокси-серверу с вашими запросами. Тем не менее, если вы знаете, что делаете, и решили, что открытый прокси-сервер работает для ваших нужд, https://cors-anywhere.herokuapp.com/ - это надежно доступный, активно поддерживаемый и работающий экземпляр https://github.com/Rob--W/cors-anywhere/ кода.

Как и в случае с другими открытыми прокси, упомянутыми здесь (пара из которых, по крайней мере, кажется, больше не доступны), способ работает так, что вместо того, чтобы ваш клиентский код отправлял запрос напрямую, например, http://foo.com, вы отправляете его https://cors-anywhere.herokuapp.com/http://foo.com и прокси добавляет необходимые заголовки Access-Control-* к ответу, который видит браузер.

7
sideshowbarker

Вы можете обойти эту проблему, используя YQL для прокси-запроса через серверы Yahoo. Это всего лишь несколько строк кода:

var yql_url = 'https://query.yahooapis.com/v1/public/yql';
var url = 'your api url';

$.ajax({
    'url': yql_url,
    'data': {
        'q': 'SELECT * FROM json WHERE url="'+url+'"',
        'format': 'json',
        'jsonCompat': 'new',
    },
    'dataType': 'jsonp',
    'success': function(response) {
        console.log(response);
    },
});

Вот ссылка с объяснением: https://vverma.net/fetch-any-json-using-jsonp-and-yql.html

7
camnesia

Если вы используете Entity Framework , похоже, что эта ошибка иногда будет выдаваться, даже если вы включили CORS. Я понял, что ошибка произошла из-за отсутствия завершения запроса. Я надеюсь, что это поможет другим в той же ситуации.

Следующий код может выдать ошибку XMLHttpRequest cannot load http://myApiUrl/login. No 'Access-Control-Allow-Origin' header is present on the requested resource.:

using (DBContext db = new DBContext())
{
    return db.Customers.Select(x => new
    {
        Name = x.Name,
        CustomerId = x.CustomerId,
    });
}

Чтобы это исправить, требуется завершающий вызов, например .ToList() или .FirstOrDefault() в конце запроса, например:

using (DBContext db = new DBContext())
{
    return db.Customers.Select(x => new
    {
        Name = x.Name,
        CustomerId = x.CustomerId,
    }).ToList();
}
5
Loyalar

В моем случае я использовал приложение JEE7 JAX-RS, и у меня отлично работали следующие приемы:

@GET
    @Path("{id}")
    public Response getEventData(@PathParam("id") String id) throws FileNotFoundException {
        InputStream inputStream = getClass().getClassLoader().getResourceAsStream("/eventdata/" + id + ".json");
        JsonReader jsonReader = Json.createReader(inputStream);
        return Response.ok(jsonReader.readObject()).header("Access-Control-Allow-Origin", "*").build();
    }
5
Bhuwan Gautam

Если вы получаете это сообщение об ошибке из браузера:

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '…' is therefore not allowed access

когда вы пытаетесь выполнить запрос Ajax POST/GET к удаленному серверу, который находится вне вашего контроля, забудьте об этом простом исправлении:

<?php header('Access-Control-Allow-Origin: *'); ?>

Вам действительно нужен, особенно если вы используете JavaScript только для выполнения Ajax-запроса, внутренний прокси, который принимает ваш запрос и отправляет его на удаленный сервер.

Сначала в своем коде JavaScript выполните Ajax-вызов на свой собственный сервер, например:

$.ajax({
    url: yourserver.com/controller/proxy.php,
    async: false,
    type: "POST",
    dataType: "json",
    data: data,
    success: function (result) {
        JSON.parse(result);
    },
    error: function (xhr, ajaxOptions, thrownError) {
        console.log(xhr);
    }
});

Затем создайте простой файл PHP с именем proxy.php, чтобы обернуть данные POST и добавить их на удаленный URL-сервер в качестве параметров. Я приведу пример того, как обойти эту проблему с помощью API поиска Expedia Hotel:

if (isset($_POST)) {
  $apiKey = $_POST['apiKey'];
  $cid = $_POST['cid'];
  $minorRev = 99;

  $url = 'http://api.ean.com/ean-services/rs/hotel/v3/list?' . 'cid='. $cid . '&' . 'minorRev=' . $minorRev . '&' . 'apiKey=' . $apiKey;

  echo json_encode(file_get_contents($url));
 }

При выполнении:

echo json_encode(file_get_contents($url));

Вы просто делаете тот же запрос, но на стороне сервера, и после этого он должен работать нормально.

Ответ скопирован и вставлен из NizarBsb

4
Flash

Я успешно смог решить (в моем случае со шрифтами) использование htaccess, но, очевидно, OP спрашивает немного иначе. Но вы можете использовать шаблон FileMatch и добавить любое расширение, чтобы оно не выдавало ошибку кросса.

<IfModule mod_headers.c>
  <FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|font.css|css)$">
    Header set Access-Control-Allow-Origin "*"
  </FilesMatch>
</IfModule>

https://httpd.Apache.org/docs/2.4/mod/core.html#filesmatch

4
Danish

Для API GoLang:

Сначала вы можете взглянуть на MDN CORS Doc , чтобы узнать, что такое CORS. Насколько я знаю, CORS - это вопрос о том, разрешать ли Origin Of Request доступ к ресурсам сервера или нет.

И вы можете ограничить, какой запрос Origin может получить доступ к серверу, установив Access-Control-Allow-Origin в Header ответа сервера.

Например, установка следующего заголовка в ответе сервера означает, что только запрос, отправленный с http://foo.example, может получить доступ к вашему серверу:

Access-Control-Allow-Origin: http://foo.example

и следующий запрос разрешения, отправленный из любого источника (или домена):

Access-Control-Allow-Origin: *

И как я знаю в сообщении об ошибке, requested resource означает ресурс сервера, поэтому No 'Access-Control-Allow-Origin' header is present on the requested resource. означает, что вы не установили заголовок Access-Control-Allow-Origin в своем ответе сервера, или, возможно, вы установили, но источник происхождения запроса не указан в Access-Control-Allow-Origin, поэтому запрос не разрешен доступ:

В запрошенном ресурсе отсутствует заголовок «Access-Control-Allow-Origin». Происхождение 'null', следовательно, не разрешено.

В GoLang я использую пакет gorilla/mux для построения сервера API на localhost:9091 и разрешаю CORS добавлять "Access-Control-Allow-Origin", "*" в заголовок ответа:

func main() { // API Server Code
    router := mux.NewRouter()
    // API route is /people,
    //Methods("GET", "OPTIONS") means it support GET, OPTIONS
    router.HandleFunc("/people", GetPeople).Methods("GET", "OPTIONS")
    log.Fatal(http.ListenAndServe(":9091", router))
}

// Method of '/people' route
func GetPeople(w http.ResponseWriter, r *http.Request) {

    // Allow CORS by setting * in sever response
    w.Header().Set("Access-Control-Allow-Origin", "*")

    w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
    json.NewEncoder(w).Encode("OKOK")
}

И я использую JavaScript в клиенте, при localhost:9092 сделать запрос Chrome может успешно получить "OKOK" с сервера localhost:9091.

function GetPeople() {
    try {
        var xhttp = new XMLHttpRequest();
        xhttp.open("GET", "http://localhost:9091/people", false);
        xhttp.setRequestHeader("Content-type", "text/html");
        xhttp.send();
        var response = JSON.parse(xhttp.response);
        alert(xhttp.response);
    }
    catch (error) {
        alert(error.message);
    }
}

Кроме того, вы можете проверить свой заголовок запроса/ответа с помощью таких инструментов, как Fiddler.

4
yu yang Jian

Популярный вопрос - еще одна вещь, на которую стоит обратить внимание, если вы прочитали это далеко, и ничто другое не помогло. Если у вас есть CDN, такой как Akamai, Limelight или аналогичный, вы можете проверить ключ кеша, который у вас есть, для URI ресурса. Если он не включает в себя значение заголовка Origin, возможно, вы возвращаете кешированный ответ при запросе от другого Origin. Мы просто потратили полдня на отладку этого. Конфигурация CDN была обновлена, чтобы включить значение Origin только для нескольких избранных доменов, которые являются нашими, и установить для него значение null для всех остальных. Кажется, это работает и позволяет браузерам из наших известных доменов просматривать наши ресурсы. Конечно, все остальные ответы являются предварительными условиями для получения здесь, но если CDN является первым прыжком в вашем браузере, это что-то для проверки. 

В нашем случае мы могли видеть некоторые запросы, поступающие в наш сервис, но не почти объем, который отправлял сайт. Это указало нам на CDN. Мы смогли вернуться и увидеть, что исходный запрос был обработан по прямому запросу, не являющемуся частью вызова браузера AJAX, а заголовок ответа Access-Control-Allow-Origin не был включен. Очевидно, CDN кеширует это значение. Настройка Akamai CDN Tweak для рассмотрения значения заголовка запроса Origin как части соответствия, кажется, заставила его работать на нас.

4
No Refunds No Returns

Много раз это случается со мной от javascript до моего php api, потому что это одна из нескольких причин. Я забыл поставить <?php header('Access-Control-Allow-Origin: *'); ? один. Это полезно для кросс-доменного доступа. Другая причина в том, что в jQuery-запросе ajax я указываю определенный dataType и возвращаю другой dataType, поэтому он выдает ошибку. 

Последнее и наиболее заметное объяснение этой ошибки - ошибка разбора на странице, которую вы запрашиваете. Если вы нажмете на URL этой страницы в своем браузере, более чем вероятно, что вы увидите ошибку синтаксического анализа и у вас будет номер строки для решения проблемы. 

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

3
Garrett Tacoronte

В запросе jsonp вы должны перехватить «jsonpCallback» и отправить его обратно.

$.ajax({
      url: lnk,
      type: 'GET',
      crossDomain: true,
      dataType: 'jsonp',
      success: function (ip) { console.log(ip.ip); },
      error: function (err) { console.log(err) }
});

На серверной стороне (если вы используете в качестве внутреннего PHP)

echo $_GET['callback'].'({"ip":"192.168.1.1"})';

В этом случае ответ сервера выглядит так: 

jQuery331009526199802841284_1533646326884 ({ "ф": "192.168.1.1"})

но вы можете установить "jsonpCallback" вручную на внешнем интерфейсе и поймать его на стороне сервера

$.ajax({
      url: lnk,
      type: 'GET',
      crossDomain: true,
      dataType: 'jsonp',
      jsonpCallback: 'get_ip',
      success: function (ip) { console.log(ip.ip); },
      error: function (err) { console.log(err) }
});

В этом случае ответ сервера выглядит так: 

get_ip ({ "ф": "192.168.1.1"})

2
Alexey Kolotsey

На моем сайте (на основе .NET) я только что добавил это:

<system.webServer>
 <httpProtocol>  
    <customHeaders>  
     <add name="Access-Control-Allow-Origin" value="*" />  
     <add name="Access-Control-Allow-Headers" value="Content-Type" />  
     <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />  
    </customHeaders>  
  </httpProtocol>         
</system.webServer>

Большое спасибо это видео.

2
FrenkyB

в случае, если вы хотите исправить это на бэкэнде (в Flask), а не на внешнем интерфейсе, я бы полностью порекомендовал пакет Python для Flask CORS. Колба Корс

С помощью одной простой строки в вашем app.py вы можете автоматически вставить стандартный заголовок разрешения любого источника или настроить его в соответствии с требованиями.

2
Ben Watts

Для полноты, Apache разрешает cors:

Header set Access-Control-Allow-Origin "http://www.allowonlyfromthisurl.com"
Header set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header set Access-Control-Max-Age "1000"
Header set Access-Control-Allow-Headers "x-requested-with, Content-Type, Accept-Encoding, Accept-Language, Cookie, Referer"
2
zak

CORS для вас.

CORS - это «Обмен ресурсами между источниками» и является способом отправки междоменного запроса. Теперь и XMLHttpRequest2, и Fetch API поддерживают CORS.

Но это имеет свои пределы. Серверу необходимо выполнить специальное требование Access-Control-Allow-Origin, и его нельзя установить на «*».

И если вы хотите, чтобы любой Origin мог отправить вам запрос, вам нужен JSONP (также необходимо установить Access-Control-Allow-Origin, но может быть и «*»).

Для большого количества запросов, если вы не знаете, что выбрать, я думаю, вам нужен полностью функциональный компонент для этого. Позвольте мне представить простой компонент catta


Если вы используете современный браузер (> Internet Explorer9, Chrome, Firefox, Edge и т.д.), Очень рекомендуется использовать простой, но красивый компонент, https://github.com/Joker-Jelly/катта. Он не имеет зависимостей, его размер составляет менее 3 КБ, и он поддерживает Fetch, Ajax и JSONP с таким же простым синтаксисом и опциями.

catta('./data/simple.json').then(function (res) {
  console.log(res);
});

Он также поддерживает все способы импорта в ваш проект, например модуль ES6, CommonJS и даже <script> в HTML.

2
Jelly

Большинство из этих ответов говорят пользователям, как добавить заголовки CORS на сервер, которым они управляют.

Однако если вам нужны данные с сервера, который вы не контролируете на веб-странице, одним из решений является создание тега сценария на вашей странице, установите для атрибута src конечную точку API, у которой нет заголовков CORS, а затем загрузите эти данные. на страницу:

window.handleData = function(data) {
  console.log(data)
};

var script = document.createElement('script');
script.setAttribute('src','https://some.api/without/cors/headers.com&callback=handleData');
document.body.appendChild(script);
2
duhaime

Я получил эту ошибку с $http.get в Angular. Мне нужно было использовать$http.jsonpвместо.

2
Travis Heeter

Может быть, это немного сложнее, но вы можете использовать веб-сервер для маршрутизации запроса . С nodejs у вас нет этой проблемы. Я не эксперт в узле JS. Так что я не знаю, чистый ли это код. 

Но это работает для меня

Вот небольшой пример:

УЗЕЛ JS

var rp = require('request-promise');
var express = require('express'),
    app = express(),
    port = process.env.PORT || 3000;
var options = {
    method: 'POST',
    uri: 'http://api.posttestserver.com/post',
    body: {
        some: 'payload'
    },
    json: true // Automatically stringifies the body to JSON
};
app.get('/', function (req, res) {
        rp(options)
        .then(function (parsedBody) {
            res.send(parsedBody)
        })
        .catch(function (err) {
            res.send(err)
        });
});
app.listen(port);

JS

axios.get("http://localhost:3000/").then((res)=>{
    console.log('================res====================');
    console.log(res);
    console.log('====================================');
})
1
KT Works

Для сервера Ruby on Rails в application_controller.rb добавьте это:

after_action :cors_set_access_control_headers

def cors_set_access_control_headers
  headers['Access-Control-Allow-Origin'] = '*'
  headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
  headers['Access-Control-Allow-Headers'] = '*'
end
1
张健健

На запрашиваемом ресурсе отсутствует заголовок «Access-Control-Allow-Origin». Происхождение ' https://sx.xyz.com ', следовательно, доступ запрещен.

Я также столкнулся с аналогичной проблемой с междоменным обменом данными в ответе Ajax как error undefined. Но ответ в заголовке был Status Code: 200 OK

Failed to load https://www.Domain.in/index.php?route=api/synchronization/checkapikey:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'https://sx.xyz.in' is therefore not allowed access.

Решение обойти это: В моем случае это было вызвать функцию checkapikey () через Ajax в другой домен и получить ответ с данными, куда был сделан вызов:

if (($this->request->server['REQUEST_METHOD'] == 'POST') && isset($this->request->server['HTTP_Origin'])) {

        $this->response->addHeader('Access-Control-Allow-Origin: ' . $this->request->server['HTTP_Origin']);
        $this->response->addHeader('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
        $this->response->addHeader('Access-Control-Max-Age: 1000');
        $this->response->addHeader('Access-Control-Allow-Credentials: true');
        $this->response->addHeader('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');

        $headers = getallheaders();
...
}
1
Nishanth ॐ

Это решение определенно подойдет вам. Добавить собственный дескриптор сообщения

public class CustomHeaderHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request, CancellationToken cancellationToken)
    {
        HttpResponseMessage response = await base.SendAsync(request, cancellationToken);
        var referrer = request.Headers.Referrer;
        if (referrer != null && !response.Headers.Contains("Access-Control-Allow-Origin"))
        {
            response.Headers.Add("Access-Control-Allow-Origin", referrer.Scheme + "://" + referrer.Authority);
        }
        return response;
    }
}

Зарегистрируйтесь в webapiconfig.cs.

config.MessageHandlers.Add (new CustomHeaderHandler ());

И если вы используете SignalR, добавьте этот код в файл globle.asax.cs

protected void Application_BeginRequest(object sender, EventArgs e)
        {
            var referrer = Request.UrlReferrer;
            if (Context.Request.Path.Contains("signalr/") && referrer != null)
            {
                Context.Response.AppendHeader("Access-Control-Allow-Origin", referrer.Scheme + "://" + referrer.Authority);
            }
        }
1
Ujjwal

Для Opera (работает так же, как Chrome), я запустил браузер с помощью этой команды:

opera --user-data-dir="~/Downloads/opera-session" --disable-web-security

Проблема решена! Теперь я могу работать с локальным файлом HTML (на моем жестком диске) и вызывать запросы Ajax для удаленных источников в одном и том же файле.

Примечание 1: Вы можете указать любую папку в вашем домашнем каталоге как --user-data-dir.

Примечание 2: Проверено на Debian 8 (Джесси)/Opera 39

 Here is a screenshot

При обычном запуске (без указанных выше параметров) тот же запрос попадает в блок кода ошибки.

0
csonuryilmaz

Возможно, вы можете скопировать ресурс с рабочего сервера на сервер разработки И настроить URL-адрес ресурса для динамической настройки. Таким образом, вы всегда будете читать из одного источника, исключая перекрестное исключение происхождения.

0
bachstein

В моем случае я использовал весеннюю загрузку в качестве службы, вы можете добавить перекрестную аннотацию Origin на ответственную операцию.

@CrossOrigin(origins = "http://localhost:4200")
@RequestMapping(value = "getFoo", method = RequestMethod.GET)
public ResponseEntity getFoo(){
    // do something
} 
0
Chandan Kumar

Я создал простой мост в своем собственном домене, который выбирает и показывает контент из внешнего домена.

<?php
header("Content-Type: text/plain");
if (isset($_GET["cnic"]))
{
    $page = file_get_contents("https://external.domain.com/api/verify/" . $_GET["cnic"]);
    echo $page;
}
else
{
    echo "";
}

?>

Теперь вместо доступа к внешнему домену в AJAX я разместил URL этого файла моста.

Вы должны настроить Content-Type в соответствии с вашими потребностями. Если данные в формате JSON, используйте header("Content-Type: application/json");

0
Muhammad Saqib

Просто упомянуть еще один способ «обойти» его - AJAX прокси. Отправьте запрос на ваш сервер, чтобы получить данные из другого источника и отправить запрос обратно к вам.

Я предпочитаю этот подход по сравнению с JSONP, потому что он имеет некоторые потенциальные проблемы безопасности.

0
carobnodrvo

Я решил эту проблему, включив CORS для URL-адреса клиента, обращающегося к веб-API, и он успешно работал.

Например:

[EnableCors(origins: "http://clientaccessingapi.com", headers: "*", methods: "*")]
0
Rizwan ali