Походження не заборонено системою Access-Control-Allow-Origin


337

Я створюю Ajax.requestвіддалений сервер PHP в додатку Sencha Touch 2 (обгорнутої в PhoneGap ).

Відповідь сервера така:

XMLHttpRequest не може завантажити http://nqatalog.negroesquisso.pt/login.php . Походження http://localhost:8888не заборонено системою Access-Control-Allow-Origin.

Як я можу виправити цю проблему?


19
при використанні JQuery, установка dataType: 'jsonp',робить трюк
Amit

11
до речі, це не відповідь від сервера. Якщо бути точним, помилка видається на стороні клієнта.
Маттео

2
JSONP трюк , ймовірно , більше не працює, FYI: stackoverflow.com/questions/12216208 / ...
drewww

7
Зауважте, оскільки я лише витрачав півдня на переслідування цієї помилки. Якщо скрипт на стороні сервера не працює з внутрішньою серверною помилкою, браузер може інтерпретувати її так, як ніби запит не був дозволений через Access-Control-Allow-Originта повідомити про це як про помилку.
troelskn

1
@troelskn Ти щойно врятував мені життя. Я шукав помилку CORS вже 3 дні, і це була просто невелика проблема з налаштуваннями Spring, яка викликала 500, які я вирішив за 5 хвилин, як тільки я прочитав ваш коментар, і я його фактично шукав. Дякую!
Олексій Дуфреной

Відповіді:


378

Нещодавно я писав статтю з цього питання, Cross Domain AJAX .

Найпростіший спосіб впоратися з цим, якщо ви маєте контроль над сервером, що відповідає, - це додати заголовок відповіді для:

Access-Control-Allow-Origin: *

Це дозволить Ajax між доменами . У PHP вам потрібно буде змінити відповідь так:

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

Ви можете просто помістити Header set Access-Control-Allow-Origin *налаштування у конфігурацію Apache або у файл htaccess.

Слід зазначити, що це ефективно вимикає захист CORS, що дуже ймовірно піддає вашим користувачам атаку . Якщо ви не знаєте, що вам спеціально потрібно використовувати підстановку, ви не повинні використовувати її, а замість цього слід додати білий список вашого домену:

<?php header('Access-Control-Allow-Origin: http://example.com') ?>

4
Я зв’яжусь зі своїм провайдером сервера. Спасибі
Рікардо

8
Чи є проблеми щодо безпеки? Наприклад, у цій відповіді йдеться про те, що "JavaScript обмежений" тією ж політикою походження "з міркувань безпеки. Наприклад, шкідливий скрипт не може зв’язатися з віддаленим сервером та надсилати конфіденційні дані з вашого сайту".
ДжонК

4
Чудово, я просто помістив це у свій файл сервера node.js: response.writeHead (200, {'Content-Type': contentType, 'Access-Control-Allow-Origin': '*'}); І це спрацювало. Дякую!
vbullinger

25
JohnK, так, wildcard дозволить будь-якому домену надсилати запити вашому хосту. Я рекомендую замінити зірочку певним доменом, на якому ви будете запускати сценарії.
Нік

7
Цікаво, що ви вважаєте, що макіяж навіть не слід пропонувати @jfrej. Все залежить від вашої мети. Наприклад, ми використовували підстановку (і опублікували цю відповідь) через те, що ми будували вбудований віджет для будь-якого веб-сайту.
Метт Момбреа

63

Якщо ви НЕ маєте контролю над сервером, ви можете просто додати цей аргумент для вашої пусковий установки Chrome: --disable-web-security.

Зауважте, що я б не використовував це для звичайного "веб-серфінгу". Для довідки див. Цю публікацію: Вимкнення політики політики щодо оригіналу в Chrome .

Якщо ви використовуєте Phonegap для того, щоб фактично створити додаток і завантажити його на пристрій, це не буде проблемою.


Дякую. Але моя програма працює на мобільних пристроях, я не можу передавати аргументи в свою обгортку веб-перегляду.
Рікардо

Ви не перевіряєте свій додаток у веб-переглядачі спочатку? Як ви налагоджуєте?
Тревіс Вебб

Так, я налагоджую у веб-переглядачі Chrome, але додаток не працює на chrome. Це буде на phonegap webview witch i can control.
Рікардо

4
прочитайте відповідь: ви можете просто додати цей аргумент до свого запуску Chrome . Немає налаштувань для цього в Chrome
Travis Webb

2
Звичайно, це небезпечно. ОП просить обходити заходи безпеки.
Тревіс Вебб

42

Якщо ви використовуєте Apache, просто додайте:

<ifModule mod_headers.c>
    Header set Access-Control-Allow-Origin: *
</ifModule>

у вашій конфігурації. Це призведе до того, що всі відповіді вашого веб-сервера будуть доступні з будь-якого іншого веб-сайту в Інтернеті. Якщо ви маєте намір дозволити сервіси вашого хоста використовувати лише певний сервер, ви можете замінити *його URL-адресою вихідного сервера:

Header set Access-Control-Allow-Origin: http://my.origin.host

3
І не забудьте завантажити модуль: заголовки a2enmod
Walery

як завантажити модуль: заголовки a2enmod?
Айеша

18

Якщо у вас є програма ASP.NET / ASP.NET MVC , ви можете включити цей заголовок через файл Web.config:

<system.webServer>
  ...

    <httpProtocol>
        <customHeaders>
            <!-- Enable Cross Domain AJAX calls -->
            <remove name="Access-Control-Allow-Origin" />
            <add name="Access-Control-Allow-Origin" value="*" />
        </customHeaders>
    </httpProtocol>
</system.webServer>

2
.NET MVC Люди, ПОШУЙТЕ тут! Я фактично збираюся набрати рішення і вказати на цю відповідь у своєму блозі, щоб люди могли знайти це простіше. Нічого гіршого, ніж намагатися пройти перешкоду .NET / MVC і не знайти нічого, крім рішення PHP / jQuery. Спасибі @ Caio-Proiete
ottoflux

1
Чому це не працює для мене? Я використовую Chrome і намагаюся отримати доступ до сторінки фінансів Yahoo з мого localhost.
новачок

1
спасибі це працювало на мене. Я додав у проект кодової сторони сервера (web.config).
ethem

15

Це було перше питання / відповідь, що з’явився для мене при спробі вирішити ту саму проблему, використовуючи ASP.NET MVC як джерело моїх даних. Я усвідомлюю, що це не вирішує питання PHP , але воно пов'язане достатньо, щоб бути цінним.

Я використовую ASP.NET MVC. Повідомлення в блозі від Грега Бранта працювало на мене. Зрештою, ви створюєте атрибут, [HttpHeaderAttribute("Access-Control-Allow-Origin", "*")]який ви можете додати до дій контролера.

Наприклад:

public class HttpHeaderAttribute : ActionFilterAttribute
{
    public string Name { get; set; }
    public string Value { get; set; }
    public HttpHeaderAttribute(string name, string value)
    {
        Name = name;
        Value = value;
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.AppendHeader(Name, Value);
        base.OnResultExecuted(filterContext);
    }
}

А потім використовувати його з:

[HttpHeaderAttribute("Access-Control-Allow-Origin", "*")]
public ActionResult MyVeryAvailableAction(string id)
{
    return Json( "Some public result" );
}

1
У WebApi 2 це вбудоване зараз. asp.net/web-api/overview/security/…
Метт Фрейр

10

Оскільки Метт Момбре відповідає правильній стороні сервера, ви можете зіткнутися з іншою проблемою, яка полягає у відхиленні білого списку.

Ви повинні налаштувати свій phonegap.plist. (Я використовую стару версію фонегапу)

Для cordova можуть бути деякі зміни в іменуванні та каталозі. Але кроки мають бути здебільшого однаковими.

Спочатку виберіть Підтримуючі файли> PhoneGap.plist

введіть тут опис зображення

потім під "Зовнішніми хостами"

Додайте запис зі значенням, можливо, " http://nqatalog.negroesquisso.pt " Я використовую * лише для налагодження.

введіть тут опис зображення


8

Це може бути зручно для тих, хто потребує винятку як для "www", так і для "non-www" версій реферала:

 $referrer = $_SERVER['HTTP_REFERER'];
 $parts = parse_url($referrer);
 $domain = $parts['host'];

 if($domain == 'google.com')
 {
         header('Access-Control-Allow-Origin: http://google.com');
 }
 else if($domain == 'www.google.com')
 {
         header('Access-Control-Allow-Origin: http://www.google.com');
 }

Вказав мені в правильному напрямку, щоб вирішити помилку ACAO лазурним способом. Поки я додав дозволене ім'я хоста googledrive. Використовувана URL-адреса повинна бути googledrive НЕ googledrive
Kildareflare

7

Я дам вам просте рішення для цього. У моєму випадку я не маю доступу до сервера. У цьому випадку ви можете змінити політику безпеки у своєму браузері Google Chrome, щоб дозволити Access-Control-Allow-Origin. Це дуже просто:

  1. Створіть ярлик браузера Chrome
  2. Клацніть правою кнопкою миші піктограму скорочення -> Властивості -> Ярлик -> Ціль

Проста вставка "C:\Program Files\Google\Chrome\Application\chrome.exe" --allow-file-access-from-files --disable-web-security.

Розташування може відрізнятися. Тепер відкрийте Chrome, натиснувши на цей ярлик.



6

Якщо ви пишете розширення Chrome і отримати цю помилку, то переконаєтеся , що ви додали базовий URL в API, щоб ваш manifest.json«s дозволу блоку , наприклад:

"permissions": [
    "https://itunes.apple.com/"
]

6

Це відбувається через політику одного походження . Дивіться більше в Мережі розробників Mozilla або Вікіпедії .

В основному, у вашому прикладі вам потрібно завантажувати http://nqatalog.negroesquisso.pt/login.phpсторінку лише з nqatalog.negroesquisso.pt, а не localhost.


1
Але мені потрібно завантажити веб-сервіс з мобільного пристрою, я б обходив це?
Рікардо

Ну, вам потрібно внести деякі зміни на стороні сервера або скористатися JSONP en.wikipedia.org/wiki/JSONP
antyrat

6

якщо ви знаходитесь під apache, просто додайте .htaccess файл у свій каталог із цим вмістом:

Header set Access-Control-Allow-Origin: *

Header set Access-Control-Allow-Headers: content-type

Header set Access-Control-Allow-Methods: *

5

У Ruby on Rails ви можете робити в контролері:

headers['Access-Control-Allow-Origin'] = '*'

в який контролер ви ставите це, якщо це дзвінок в Ajax? Чи можу я побачити більше кодового контексту?
rigdonmr

5

Ви можете змусити його працювати без зміни сервера, зробивши броузер, включаючи заголовок Access-Control-Allow-Origin: *у відповіді HTTP OPTIONS.

У Chrome використовуйте це розширення . Якщо ви перебуваєте в Mozilla, перевірте цю відповідь .


5

Якщо ви отримаєте це в Angular.js, переконайтесь, що ви уникаєте номера порту так:

var Project = $resource(
    'http://localhost\\:5648/api/...', {'a':'b'}, {
        update: { method: 'PUT' }
    }
);

Дивіться тут для отримання додаткової інформації.


4

У нас також є проблема з програмою phonegap, протестованою в хромі. Один автомат Windows, який ми використовуємо нижче пакетного файлу щодня перед відкриттям Chrome. Запам’ятайте перед тим, як запустити це, вам потрібно очистити всі екземпляри хрому від менеджера завдань, або ви можете вибрати хром, щоб не працювати у фоновому режимі.

ПАРТІЯ: (використовувати cmd)

cd D:\Program Files (x86)\Google\Chrome\Application\chrome.exe --disable-web-security


0

Коли ви отримаєте запит, ви можете

var origin = (req.headers.origin || "*");

ніж тоді, коли вам доведеться відповісти, рухайтеся з чимось таким:

res.writeHead(
    206,
    {
        'Access-Control-Allow-Credentials': true,
        'Access-Control-Allow-Origin': origin,
    }
);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.