Я пытаюсь сделать авторизацию с помощью JavaScript, подключившись к API RESTful, построенному в Flask. Однако, когда я делаю запрос, я получаю следующую ошибку: XMLHttpRequest не может загрузить http: // myApiUrl / login. В запрошенном ресурсе нет заголовка «Access-Control-Allow-Origin». Поэтому исходный 'null' не допускается.
Я знаю, что API или удаленный ресурс должен установить заголовок, но почему он работал, когда я сделал запрос через расширение Chrome JavaScript ?
Это код запроса:
$.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);
});
В Ajax есть проблема с междоменным доступом. Вы должны быть уверены, что получаете доступ к своим файлам на одном и том же пути http:// без www. (или доступ из http://www. и сообщение по тому же пути, что и www.), который браузер считает другим доменом при доступе через www., поэтому вы видите, где проблема. Вы отправляете в другой домен, и браузер блокирует поток из-за ошибки источника.
Если API не размещен на том же хосте, который вы запрашиваете, поток блокируется, и вы будете необходимо найти другой способ связи с API.
У меня была следующая конфигурация, приводящая к той же ошибке при запросе ответов с сервера.
На стороне сервера: 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")}
});
В моем случае я использовал приложение 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();
}
Если вы НЕ хотите:
Отключить веб-безопасность в Chrome Использовать JSONP Используйте сторонний сайт для перенаправления ваших запросов, и вы уверены, что на вашем сервере есть Затем CORS разрешил (проверьте CORS здесь: http://www.test-cors.org/)
Затем вам нужно передать исходный параметр с вашим запросом. Это начало ДОЛЖНО соответствовать тому, что ваш браузер отправляет с вашим запросом.
Вы можете увидеть его в действии здесь: http://www.test-cors.org/
Функциональность редактирования отправляет GET & amp; POST-запрос в другой домен для извлечения данных. Я устанавливаю параметр origin, который решает проблему.
tldr: добавьте параметр «происхождение» к вашим вызовам, которые должны быть параметром Origin, который отправляет ваш браузер (вы не можете обманывать исходный параметр)
Основываясь на ответе от пользователя shruti, я создал ярлык браузера Chrome с необходимыми аргументами:
Я успешно смог (в моем случае для шрифтов) использовать htaccess, но, очевидно, OP задает немного разные. Но вы можете использовать шаблон FileMatch и добавлять любое расширение, чтобы он не выдавал ошибку cros.
<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
Большинство этих ответов говорят пользователям, как добавлять заголовки 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);
На моем веб-сайте (на основе .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>
Большое спасибо этому видео.
Много раз это происходит со мной от javascript к моему php api, потому что одна из нескольких причин. Я забыл поставить <?php header('Access-Control-Allow-Origin: *'); ? один. Это полезно для доступа к перекрестным доменам. Другая причина заключается в том, что в jQuery ajax-запросе я указываю конкретный тип данных и возвращаю другой тип данных, поэтому он выдает ошибку.
Последний и наиболее известный аргумент в пользу этой ошибки - на странице, которую вы запрашиваете, есть ошибка синтаксического анализа. Если вы нажмете URL-адрес этой страницы в своем браузере, более вероятно, вы увидите ошибку синтаксического анализа, и у вас будет номер строки для решения проблемы.
Надеюсь, это поможет кому-то. Мне потребовалось некоторое время, чтобы отладить это, и я бы хотел, чтобы у меня был контрольный список вещей для проверки.
Так как $ .ajax ({type: "POST" - Calls OPTIONS $ .post (- Calls POST
) - это разные почтовые сообщения «POST», но когда мы называем это «ОПЦИИ»,
$. ajax ({type: "POST"
Пожалуйста, добавьте следующий код в свой файл web.config под тегом & lt; system.webServer & gt; Это будет работать
<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");
}
});
Угловая проблема 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");
Если вы можете иметь дело с JSON взамен, попробуйте использовать JSONP (обратите внимание на P в конце) для разговора между доменами:
$.ajax({
type: "POST",
dataType: 'jsonp',
...... etc ......
Возможно, это немного сложнее, но вы можете использовать веб-сервер для маршрутизации запроса. С nodejs вы не имеете этой проблемы. Я не эксперт в узле js. Поэтому я не знаю, является ли это чистым кодом.
Но это работает для меня
Вот несколько примеров:
NODE 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);
NODE JS [ ! d4]
axios.get("http://localhost:3000/").then((res)=>{
console.log('================res====================');
console.log(res);
console.log('====================================');
})
У меня была проблема с этим, когда я использовал 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>
Это очень просто решить, если вы используете PHP. Просто добавьте следующий скрипт в начале вашей страницы PHP, который обрабатывает запрос:
<?php header('Access-Control-Allow-Origin: *'); ?>
Внимание! Это содержит проблему безопасности вашего PHP-файла, которую он мог бы называть злоумышленниками. вы должны использовать сеансы и файлы cookie для проверки подлинности, чтобы предотвратить ваш файл / службу от этой атаки.
Если вы используете 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"
},
Популярный вопрос - Еще одна вещь, на которую нужно смотреть, если вы читали это далеко, и ничего больше не помогло. Если у вас есть CDN, например Akamai, Limelight или подобное, вы можете проверить ключ кеша, который у вас есть для URI ресурса. Если он не содержит значение заголовка Origin, вы можете вернуть ответ в кешированный запрос по другому источнику. Мы просто потратили полдня на отладку. Конфигурация CDN была обновлена, чтобы включать только значение Origin для нескольких выбранных доменов, которые являются нашими, и установить для него значение null для всех остальных. Это похоже на работу и позволяет браузерам из наших известных доменов просматривать наши ресурсы. Конечно, все остальные ответы являются предпосылками для получения здесь, но если CDN является первым переходом из вашего браузера, это то, что нужно рассмотреть.
В нашем случае мы могли видеть, как некоторые запросы поступают к нашей службе, но не к тому объему, который отправлял сайт. Это указывало нам на CDN. Мы смогли вернуться и посмотреть, что исходный запрос был подан с помощью прямого запроса, а не части вызова AJAX браузера, и заголовок ответа Access-Control-Allow-Origin не был включен. По-видимому, CDN кэшировал это значение. Конфигурация конфигурации Akamai CDN, чтобы рассмотреть значение заголовка запроса Origin как часть совпадения, похоже, заставила его работать для нас.
Легкий способ - просто добавить расширение в google chrome, чтобы разрешить доступ с помощью CORS.
(https://chrome.google.com/webstore/detail/allow-control -allow-origi / nlfbmbojpeacfghkpbjhddihlkkiljbi? hl = en-US)
Просто включите это расширение, когда вы хотите разрешить доступ к запросу заголовка «access-control-allow-origin».
'access-control-allow-origin'
В Windows вставьте эту команду в окно запуска
chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security
, это откроет новый запустите браузер , который разрешает доступ к запросу заголовка «access-control-allow-origin».
Попробуйте XDomain,
Резюме: Чистая альтернатива JavaScript / CORS для JavaScript. Не требуется настройка сервера - просто добавьте proxy.html в домене, с которым вы хотите общаться. Эта библиотека использует XHook для подключения всех XHR, поэтому XDomain должен работать совместно с любой библиотекой.Я хочу, чтобы кто-то поделился этим сайтом со мной давным-давно http://cors.io/, он бы сэкономил массу времени по сравнению со строительством и полагался на мой собственный прокси. Однако, когда вы переходите к производству, ваш собственный прокси-сервер является лучшим выбором, поскольку вы все еще контролируете все аспекты своих данных.
Все, что вам нужно:
https://cors.io/?http://HTTP_YOUR_LINK_HERE