Происхождение не разрешено 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 ограничен« той же политикой происхождения »по соображениям безопасности. Например, вредоносный скрипт не может связаться с удаленным сервером и отправить конфиденциальные данные с вашего сайта».
JohnK

4
Круто, я просто поместил это в файл моего сервера node.js: response.writeHead (200, {'Content-Type': contentType, 'Access-Control-Allow-Origin': '*'}); И это сработало. Спасибо!
Vbullinger

25
ДжонК, да, подстановочный знак позволит любому домену отправлять запросы на ваш хост. Я рекомендую заменить звездочку конкретным доменом, на котором вы будете запускать скрипты.
Ник

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

63

Если вы не имеете контроля над сервером, вы можете просто добавить этот аргумент для вашей пусковой установки Chrome: --disable-web-security.

Обратите внимание, что я бы не использовал это для обычного «веб-серфинга». Для справки см. Этот пост: Отключить ту же политику происхождения в Chrome .

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


Спасибо. Но мое приложение работает на мобильных устройствах, я не могу передать аргументы своей оболочке webview.
Рикардо

Разве вы сначала не тестировали свое приложение в браузере? Как вы отлаживаете?
Трэвис Уэбб

Да, я отлаживаю в браузере Chrome, но приложение не будет работать на Chrome. Это будет на веб-обозревании, которое я не могу контролировать.
Рикардо

4
Прочтите ответ: вы можете просто добавить этот аргумент в свою панель запуска Chrome . Там нет установки для этого внутри Chrome
Трэвис Уэбб

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 Strauch

Как загрузить модуль: 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 с моего локального хоста.
новичок

1
спасибо, это сработало для меня. Я добавил в проект кода на стороне сервера (web.config).
Этхемы

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. (Я использую старую версию телефонного зазора)

Для кордовы могут быть некоторые изменения в именовании и каталоге. Но шаги должны быть в основном одинаковыми.

Сначала выберите Вспомогательные файлы> PhoneGap.plist

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

затем в разделе "Внешние хосты"

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

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


8

Это может быть удобно для тех, кому нужно исключение для версий реферера как с www, так и без 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 Developer Network или Википедии .

По сути, в вашем примере вам нужно загружать 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, протестированным в Chrome. Одна машина Windows, которую мы используем ниже пакетного файла каждый день перед открытием Chrome. Помните, что перед запуском вам нужно очистить весь экземпляр Chrome из диспетчера задач, или вы можете выбрать Chrome, чтобы не запускать его в фоновом режиме.

BATCH: (используйте 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.