Питання Чому у менеджера JavaScript з'являється помилка "Не" Access-Control-Allow-Origin "на запитуваному ресурсі", коли Postman не робить?


Я намагаюся зробити авторизацію за допомогою JavaScript підключившись до RESTful  API вбудований Фляга. Однак, коли я роблю запит, я отримую таку помилку:

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);
    });

1869
2017-11-17 19:29


походження


Ви виконуєте запит із localhost або виконуєте HTML безпосередньо? - MD. Sahib Bin Mahboob
@ MD.SahibBinMahboob Якщо я розумію ваше запитання, я роблю запит від localhost - у мене є сторінка на моєму комп'ютері та просто запустіть її. Коли я розгортаю сайт на хостингу, він отримував той же результат. - Mr Jedi
- це домен вашої сторінки, що виконується, і запитуване ім'я домену однакове або інше? - MD. Sahib Bin Mahboob
багато пов'язаних: stackoverflow.com/questions/10143093/... - cregox
Для тих, хто шукає більше читання, MDN має хорошу статтю про запити ajax та крос-походження: developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS - Sam Eaton


Відповіді:


Якщо я зрозуміла це правильно, ви робите це XMLHttpRequest в інший домен, ніж ваша сторінка включена. Таким чином, браузер блокує його, оскільки це зазвичай дозволяє запит у тому ж джерелі з міркувань безпеки. Вам потрібно зробити щось інше, коли ви хочете зробити міждоменний запит. Підручник про те, як це досягти Використання CORS.

Коли ви використовуєте пошттер, вони не обмежуються цією політикою. Цитата з Перехресні XMLHttpRequest:

Регулярні веб-сторінки можуть використовувати об'єкт XMLHttpRequest для надсилання та отримання даних з віддалених серверів, але вони обмежені однаковою політикою походження. Розширення не настільки обмежені. Розширення може поговорити з віддаленими серверами поза межами його походження, якщо воно спочатку запитує дозволи для перехресного походження.


1008
2017-11-17 19:49



Ти маєш рацію. Я роблю запит до іншого домену, ніж на моїй сторінці. API знаходиться на сервері, і я запускаю запит з localhost. Перш ніж приймати відповідь, чи можете ви пояснити, що означає "безпосередньо виконувати запит"? POSTMAN не використовують домен? - Mr Jedi
Браузер не блокує запит. Єдиними веб-переглядачами, які прямо блокують перехресні відправлення ajax-запитів, є IE7 або старіші. Всі веб-переглядачі, крім IE7 та старших, реалізують специфікацію CORS (частково IE8 та IE9). Все, що вам потрібно зробити, це вибрати запити CORS на сервері API, повернувши відповідні заголовки на основі запиту. Ви повинні ознайомитися з концепціями CORS у mzl.la/VOFrSz. Поштовий посилає запити через XHR також. Якщо ви не бачите такої ж проблеми при використанні поштового менеджера, це означає, що ви несвідомо не надсилаєте той самий запит через поштового менеджера. - Ray Nicholus
@ MD.SahibBinMahboob Postman НЕ посилає запит "з вашого java / python" коду. Він надсилає запит безпосередньо з браузера. XHR у розширеннях Chrome працює трохи по-іншому, особливо якщо це стосується запитів про взаєморозимість. - Ray Nicholus
@yves це веб-переглядач, який насправді наклав правило. Таким чином, ініціювання запиту з будь-яких місць, а не браузер повинен працювати файл - MD. Sahib Bin Mahboob
@SuhailGupta, якщо ви дозволите витоки на своєму сервері, то буде дозволено виконувати запит, який насправді називається CORS. - MD. Sahib Bin Mahboob


Це не виправлення для виробництва або коли додаток повинен бути показаний клієнту, це корисно тільки для інтерфейсу користувача та настільного комп'ютера розвиток  знаходяться на іншому сервери і у виробництві вони насправді на тому ж сервері. Наприклад: Під час розробки користувальницького інтерфейсу для будь-якої програми, якщо існує потреба в тестуванні локально, вказуючи його на бек-сервер, у цьому сценарії це ідеальне виправлення. Для виправлення виробів заголовки CORS повинні бути додані на сервер бекенда, щоб дозволити перехресне отримання доступу до походження.

Простий спосіб полягає в тому, щоб просто додати розширення в Google Chrome, щоб дозволити доступ за допомогою CORS.

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

Просто ввімкніть це розширення, коли хочете дозволити доступ до ні 'access-control-allow-origin' запит на заголовок

Or 

У Windows вставте цю команду в біжи вікно

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

це відкриє новий хром браузер, який дає доступ до ні 'access-control-allow-origin' запит на заголовок


450
2018-03-04 06:42



Це чудово, але клієнтам не можна попросити запустити chrome таким чином, щоб забезпечити внутрішню вимогу до виклику веб-служби. - Taersious
це не слід приймати як відповідь, встановлюючи сторонній плагін для виправлення свого додатка, а не розуміючи CORS та виправлення вашого додатка, як інші користувачі використовуватимуть ваш API? Ви зробите їх все встановити цей плагін - James Kirkby
Я встановив це розширення і зробив запит, ніж перевірив запит у скрипалі, вказано наступне -> Походження: evil.com . Схоже, це розширення змінює походження до evil.com - wagwanJahMan
Це розширення працює як чарівність. Але насправді що вони роблять всередині? Чи є спосіб зробити те ж саме в Javascript або Jquery, а не використовувати плагін? - sms
Я думаю, це дійсно чудова відповідь якщо вам не потрібний постійний виправлення, або якщо вам потрібні лише тимчасові вимкнені корективи. Це те, що мені потрібно, і це рішення працювало чудово. Очевидно, що це ніколи не можна вважати постійним рішенням. - jtcotton63


Якщо ти можеш мати справу JSON а потім спробуйте скористатись JSONP (зверніть увагу на Р. в кінці) для спілкування між доменами:

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

Дізнайтеся більше про роботу з JSONP тут:

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


312
2018-02-22 00:42



Майте на увазі, що jsonp не працює для вмісту POST. Більше дискусій тут. - Prabu Raja
Як це так багато голосів, коли ви не можете використовувати jsonp з запитами POST?!?! - fatlog
Коли ви використовуєте JSONP, $ .ajax буде ігноруватися type, так це завжди GET що означає, що ця відповідь завжди буде працювати. - noob
Схоже, більше 200 людей просто не отримують цього - cs01
Також зауважте, що JSONP не є безпосередньо взаємозамінними з JSON. Вам потрібно сервер для повернення даних у форматі JSONP теж. Просто змінити dataType в параметрах запиту AJAX самостійно не збирається працювати. - Rory McCrossan


Це дуже просто вирішити, якщо ви використовуєте PHP. Просто додайте наступний скрипт на початку своєї сторінки PHP, яка обробляє запит:

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

УВАГА: Це містить проблему безпеки для вашого PHP-файлу, яка може бути викликана зловмисниками. вам потрібно використовувати сеанси та файли cookie для автентифікації, щоб запобігти вашому файлу / службі проти цієї атаки. Ваша служба є вразливою для Перехресне запит підробки (CSRF).

Якщо ви використовуєте Вузол-червоний ви повинні дозволити 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"
},

185
2017-12-03 20:24



Питання не про PHP взагалі. - mknaf
і це не безпечно - llazzaro
Ви не повинні вимкнути CORS, тому що ви не знаєте, що це за. Це страшна відповідь. - meagar♦
Хоча це може й не бути захищеною, питання не стосувалося безпеки, а як виконати завдання. Це один із варіантів, який розробник має обрати, коли він займається міждоменними запитами AJAX. Це допомогло мені вирішити проблему, і для моєї програми мені не подобається, звідки надходять дані. Я санітарнізую всі вхідні дані з PHP на домен призначення, отже, якщо хтось хоче опублікувати якийсь небажаний вміст, дозвольте їм спробувати. Головне тут - міждоменний AJAX може бути дозволений з домену призначення. +1 для відповіді. - ZurabWeb
Хоча я погоджуюсь із загальним повідомленням, яке надає П'єро, це не конкретно про безпеку, а безпека - це турбота. Я думаю, що це має принаймні сказати щось на кшталт: «Це, як правило, погано! Не робіть цього, якщо не знаєте, що ви робите! Ось ще більше документів на ньому: ...», а може, коротко пояснити, чому. Я б не хотів, щоб хтось приїхав сюди, і просто подумав: «О, я можу просто додати / налаштувати цей заголовок, і я добре!» і не знаю повних розв'язок. Я маю на увазі, це належить їм досліджувати і все, але все-таки. - Thomas F.


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

Все, що вам потрібно:

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


143
2017-07-21 22:08



Які недоліки цього? Ці хлопці перехоплюють мої дані? - Sebastialonso
cors.io/?u=HTTP_YOUR_LINK_HERE     (невелика корекція) - jkpd
Я не думаю, що надсилання ваших даних через проксі-сервер 3-ї сторони - це гарна ідея - Daniel Alexandrov
Одним з недоліків є те, що вони іноді перевантажені, як зараз. This application is temporarily over its serving quota. Please try again later. - Daniel Hickman
спробуй теж https://crossorigin.me/http://example.com - KingRider


Використовуючи Ajax, існує міждоменна проблема. Ви повинні бути впевнені, що ви отримуєте доступ до своїх файлів однаково http:// шлях без www. (або доступ з http://www. і розмістити на тому ж шляху, в тому числі www.), який браузер розглядає як інший домен при доступі через a www. шлях, так що ви бачите, де проблема. Ви надсилаєте повідомлення до іншого домену, і веб-переглядач блокує потік через проблему походження.

Якщо API не розміщується на тому ж хості, на якому ви запитуєте, потік заблоковано, і вам потрібно буде знайти інший спосіб спілкування з API.


61
2018-03-12 08:53



Так, я був примушений до цього в моєму додатку phonegap, var app_url = location.protocol + '//' + location.host + '/ api /. проблема була на сайті з www. Заздалегідь принесе цю помилку. - Sir Lojik


Якщо ви використовуєте 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


55
2018-02-12 16:27



Я даю тобі голосування, бо це саме те, що мені потрібно. Але вважаю поганою ідеєю рекламувати приклад "*", не пояснюючи, що це дозволить будь-яке з'єднання і не повинно використовуватись у виробництві. Це пояснюється на посиланнях MDN developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS. - rob
@ Спасибо за ваш коментар. Ви маєте рацію, ми повинні вказати, які джерела дозволяють використовувати ресурси. Але якщо ресурси використовуються для суспільних цілей, і ми не знаємо споживачів, я думаю, що ми повинні йти з "*", якщо я не помиляюся. - Nguyen Tran
Я застосував це поняття, і моє питання вирішено в nodejs. Дякую - Deepak Bhatta
app.use (функція (req, res, next) {res.setHeader ('Access-Control-Allow-Origin', '*'); res.setHeader ('Access-Control-Allow-Methods', 'GET, POST' , OPTIONS, PUT, PATCH, DELETE); res.setHeader ('Access-Control-Allow-Headers', 'X-Requested-With, тип контенту, авторизація'); res.setHeader ('Access-Control-Allow' -Відповідальності ', true); if (' OPTIONS '=== req.method) {res.send (204);} else {next ();}}); - Ricky sharma
Що стосується небезпеки використання "Access-Control-Allow-Origin", "*", побачити security.stackexchange.com/a/45677. tldr: Специфікація W3 фактично радить, що: Ресурс, який є загальнодоступним, без перевірок контролю доступу, завжди може безпечно повернути заголовок Access-Control-Allow-Origin, значення якого "*" - CODE-REaD


Оскільки
$ .ajax ({type: "POST"  - дзвінки ВАРІАНТИ 
$ .post ( - дзвінки POST 

обидва різні Поштовий виклик "POST" правильно, але, коли ми називаємо це, буде "ОПЦІЇ"

Для веб-служб 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");
    }
});

Кутовий номер 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");

41
2017-12-13 13:02



Ця конфігурація вирішила таку ж помилку на Wordpress у службах Azure. Дякую. - Andre Mesquita
Я б запропонував використовувати певне значення походження, щоб уникнути запитів від зовнішніх доменів. Так, наприклад, замість * використовувати https://www.myotherdomain.com - pechar


Спробуй XDomain,

Резюме: чистий JavaScript CORS альтернатива / polyfill. Немає конфігурації сервера - просто додайте proxy.html до домену, з яким ви хочете зв'язатися. Ця бібліотека використовує XHook для підключення всіх XHR, тому XDomain повинна працювати в поєднанні з будь-якою бібліотекою.


22
2018-04-01 07:46