Веб-API WCF RESTful не разрешен Access-Control-Allow-Origin - PullRequest
2 голосов
/ 10 июня 2011

Похоже, у меня проблема с междоменным доступом.Я видел некоторые решения, которые указывают на добавление «Access-Control-Allow-Origin: *», но я не знаю, где я могу это сделать.

Нужно ли мне создать какой-нибудь обработчик?

Я использую веб-API WCF.

Ошибка: не удается загрузить XMLHttpRequest http://localhost:8081/Song/0. Источник http://localhost:8080 не разрешен Access-Control-Allow-Происхождение.

РЕДАКТИРОВАТЬ

Я заметил, что это происходит только тогда, когда HTTP-метод PUT или DELETE.Я могу успешно делать запросы с помощью GET или POST.

Я делаю запрос с помощью jquery.

$.ajax({
        url: Settings.RESTfulEndPointFor('Song/' + songID),
        type: 'DELETE',
        success: function (response) {
            callback(response);
        }
    });

Я не знаю почему, но, похоже, это приводит к методуОПЦИИ с Access-Control-Request-Method: DELETE.

Кто-нибудь знает, что вызвало это?

Любая помощь приветствуется.

Ответы [ 6 ]

4 голосов
/ 29 октября 2012

У меня была эта проблема при подключении к службе WCF RESTful через вызовы AJAX

Мой JavaScript был таким:

var GetData= function(){

    var data;
    $.ajax({
        url:  this.server + "/data",
        async: false,
        type: "GET",
        success: function (success) {
            data = success;
        }
    });
    return data;

};

Моя конечная точка службы была открыта с этим кодом

ServiceHost host = new ServiceHost(new MyService());
host.Open();

Все важные данные хранятся в файле App.config, мне не нужно было менять этот файл для этого исправления.

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

После некоторого поиска и взлома я обнаружил свойство Authorization объекта ServiceHost. Свойство Authorization является экземпляром класса ServiceAuthorizationBehavior, чьи объекты имеют свойство ServiceAuthorizationManager, которое является экземпляром класса ServiceAuthorizationManager.

Создав новый класс, который наследуется от ServiceAuthorizationManager, и установив его в свойстве ServiceAuthorizationManager поведения Authorization вашего экземпляра ServiceHost, вы можете перехватывать все вызовы вашей службы.

Так я реализовал свой класс

public class MyServiceAuthorizationManager : ServiceAuthorizationManager
{
protected override bool CheckAccessCore(OperationContext operationContext)
{

    HttpResponseMessageProperty prop = new HttpResponseMessageProperty();
    prop.Headers.Add("Access-Control-Allow-Origin", "*");
    operationContext.OutgoingMessageProperties.Add(HttpResponseMessageProperty.Name, prop);

    return true;
}
}

затем сразу после того, как я объявил свой объект ServiceHost (до открытия хоста), я добавляю эту строку

host.Authorization.ServiceAuthorizationManager = new MyServiceAuthorizationManager();

После этого, восстановления и запуска моей службы сообщение об ошибке перестало отображаться. Ура!

Наконец, я прочитал статью, в которой описывался класс ServiceHost, предназначенный для служб SOAP / WSDL, а не служб RESTful. Для сервисов RESTful следует использовать объект WebServiceHost.

Итак

ServiceHost host = new ServiceHost(new MyService());
host.Open();

становится

WebServiceHost host = new WebServiceHost(new MyService());
host.Open();

Вы должны добавить ссылки на следующие сборки:

  • System.ServiceModel.Web

Надеюсь, это поможет.

Источники:

1 голос
/ 27 января 2012

Запрос, который вы видите с помощью метода OPTIONS и заголовка Access-Control-Request-Method: DELETE, называется «предварительным запросом». Спецификация CORS требует этого для запросов с методами, которые имеют побочные эффекты (например, DELETE), чтобы убедиться, что ресурс соответствует запросу.

Проверьте этот раздел спецификации >> http://www.w3.org/TR/cors/#cross-origin-request-with-preflight0

К сожалению, я не знаю, как заставить этот тип запроса работать с wcf web api.

1 голос
/ 10 июня 2011

Обычно вы помещаете это в заголовок ответа. Поэтому поместите его в заголовок, где вы изменяете / вставляете другие значения заголовка, такие как

header('Access-Control-Allow-Origin: *) //change it according to however header is  set in wcf , since this is php syntax

Дело в том, что ваш ответ должен иметь этот заголовок.

0 голосов
/ 25 января 2012

Во-первых, в большинстве веб-браузеров нет способа обойти междоменное ограничение.Большинство даже не позволит вам изменить заголовок «принять».Поэтому вы должны использовать JSONP.JSONP - это способ получения данных JSON из междоменной службы, но он возвращается в форме фрагмента JavaScript, что разрешено.Это работает так, что вы предоставляете сервису имя функции обратного вызова, а затем междоменная служба возвращает простой javascript с фактическими значениями JSON, встроенными в качестве параметров в функцию обратного вызова.Это действительно легко сделать сейчас с помощью WCF WebApi (превью 6).Установите его в VS 2010 с помощью NuGet.После того, как вы его установили, посмотрите здесь для получения дополнительной информации.

0 голосов
/ 26 декабря 2011

Я получил это для работы, используя следующие заголовки ответа:

res.writeHead(200, {
        'Content-Type': 'text/plain',
        'Access-Control-Allow-Methods': 'DELETE, POST, GET, OPTIONS',
        'Access-Control-Allow-Origin': '*'
    }); 
0 голосов
/ 11 июня 2011

Я создал

AllowCrossDomainRequestHandler : DelegatingChannel 

и для каждого ответа я регистрирую этот заголовок:

response.Headers.Add("Access-Control-Allow-Origin", "*"); 
...