IE10 не добавляет заголовок источника для запросов CORS в домен с тем же путем к хосту, но с другим портом #

Это сводит меня с ума. Я взломал базовую реализацию автономного сервера WebAPI и клиента MVC4. Они находятся в отдельных решениях и настроены для работы на разных портах. Запросы CORS работали нормально в браузерах, которые я тестировал (IE10/FF/Chrome) на днях, но теперь IE10 внезапно прекратил добавлять заголовок Origin к запросам. Сейчас я испытываю это на своем домашнем компьютере в этом странном примере, а также в реализации, над которой я работаю на работе.

Я пробовал каждую комбинацию, которую мог придумать в поиске Google, чтобы увидеть, испытывает ли это кто-то еще и нашел ли решение. Самой близкой мне была эта ссылка на отзыв о Microsoft Connect, которая до сих пор не решена.

Я пробовал менять порты, делать новые проекты, очищать кеш браузера; Вы называете это, я попробовал это (за исключением того, что заканчивает тем, что работал, очевидно!).

Вот заголовки запроса для запроса Get с использованием Firefox: Примечание: мне пришлось добавить пробелы для заголовков Referer и Origin с ограничением localhost в ссылках

Хост: localhost:60000

Пользователь-агент: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0

Принять: приложение / JSON, текст / Javascript, /; д =0,01

Accept-Language: en-US, en; q =0,5

Accept-Encoding: gzip, выкачать

Реферер: http:// localhost:50954/

Происхождение: http: // localhost: 50954

Подключение: keep-alive

Вот заголовки запроса для того же запроса Get, использующего IE10:

Реферер: http:// localhost:50954/

Принять: приложение / JSON, текст / Javascript, /; д =0,01

Accept-Language: en-US

Accept-Encoding: gzip, выкачать

Пользователь-агент: Mozilla / 5.0 (совместимый; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)

Подключение: Keep-Alive

DNT: 1

Хост: localhost:60000

Заголовок Origin отсутствует в IE10 и для других методов HTTP.

Вот соответствующий код для примера приложения MVC4:

Главная /Index.cshtml:

@section scripts 
{
    <script type="text/javascript">
        $(document).ready(function () {
            $('#details').click(function () {
                $('#employee').empty();
                $.getJSON("http://localhost:60000/api/employees/12345", function (employee) {
                    var now = new Date();
                    var ts = now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds();
                    var content = employee.Id + ' ' + employee.Name;
                    content = content + ' ' + employee.Department + ' ' + ts;
                    $('#employee').append($('<li/>', { text: content }));
                })
            });

            $('#update').click(function () {
                $('#employee').empty();
                $.ajax({
                    type: 'PUT',
                    url: "http://localhost:60000/api/employees/12345",
                    data: { 'Name': 'Beansock', 'Department': 'Nucular Strategory' },
                    success: function (employee) {                        
                        var now = new Date();
                        var ts = now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds();
                        var content = employee.Id + ' ' + employee.Name;
                        content = content + ' ' + employee.Department + ' ' + ts;
                        $('#employee').append($('<li/>', { text: content }));
                    },
                    error: function (error) {
                        console.log('Error:', error);
                    }
                });
            });
        });
    </script>
}

<div>
    <div>
        <h1>Employees Listing</h1>
        <input id="search" type="button" value="Get" />
        <input id="details" type="button" value="Details" />
        <input id="update" type="button" value="Update" />
    </div>
    <div>
        <ul id="employees"></ul>
    </div>
    <div>
        <ul id="employee"></ul>
    </div>    
</div>

А вот подходящие классы из образца WebAPI с собственным хостом:

Program.cs

class Program
{
    private static readonly Uri Address = new Uri("http://localhost:60000");

    static void Main(string[] args)
    {
        HttpSelfHostServer server = null;
        HttpSelfHostConfiguration config = null;

        // create new config
        config = new HttpSelfHostConfiguration(Address) { HostNameComparisonMode = HostNameComparisonMode.Exact };

        // set up routing
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional });

        // set up handlers
        config.MessageHandlers.Add(new CorsHandler());

        // create server
        server = new HttpSelfHostServer(config);

        server.OpenAsync().Wait();
        Console.WriteLine("Server is up and running.");
        Console.ReadLine();
    }
}

EmployeesController.cs

public class EmployeesController : ApiController
{
    public HttpResponseMessage Get(int id)
    {   
        var employee = new Employee()
        {
            Id = id,
            Name = "Chucky Chucky Chuck",
            Department = "Profreshies"
        };

        var response = Request.CreateResponse<Employee>(HttpStatusCode.OK, employee);            

        return response;
    }

    public HttpResponseMessage Put(Employee emp)
    {
        //employee2 = emp;
        var response = Request.CreateResponse<Employee>(HttpStatusCode.OK, emp);
        return response;
    }

    Employee employee2 = new Employee()
    {
        Id = 12345,
        Name = "Jimmy John John",
        Department = "Slow Lorisesssessss"
    };
}

internal class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Department { get; set; }
}

CorsHandler.cs

        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        // if the request is coming from a browser supporting CORS
        if (request.Headers.Contains("Origin"))
        {
            // if the Request Origin does not match a server list of valid origins, or
            // if the Request Host does not match the name of this server (to help prevent DNS rebinding attacks)
            // return a 403 Forbidden Status Code
            var origin = request.Headers.GetValues("Origin").FirstOrDefault();
            var host = request.Headers.GetValues("Host").FirstOrDefault();
            if (validOrigins.Contains(origin) == false || !host.Equals(validHost))
                return Task<HttpResponseMessage>.Factory.StartNew(() => new HttpResponseMessage(HttpStatusCode.Forbidden));


            // if the Request is not a simple one, IE: POST, PUT, DELETE, then handle it through an OPTIONS Preflight
            if (request.Method == HttpMethod.Options)
            {
                var methodRequested = request.Headers.GetValues("Access-Control-Request-Method").FirstOrDefault();
                var response = new HttpResponseMessage(HttpStatusCode.OK);
                response.Headers.Add("Access-Control-Allow-Origin", origin);
                response.Headers.Add("Access-Control-Allow-Methods", methodRequested);

                return Task<HttpResponseMessage>.Factory.StartNew(() => response);
            }
            else // if Request is a GET or HEAD, or if it has otherwise passed the Preflight test, execute here
            {
                return base.SendAsync(request, cancellationToken)
                    .ContinueWith((task) =>
                    {
                        var response = task.Result;
                        response.Headers.Add("Access-Control-Allow-Origin", origin);

                        return response;
                    });
            }
        }

        return base.SendAsync(request, cancellationToken)
                   .ContinueWith((task) => task.Result);
    }

    private IList<string> validOrigins = new List<string>() { "http://localhost:50954" };
    private string validHost = "localhost:60000";
}

Я думаю, что это должно быть все, что вам нужно, чтобы воссоздать сценарий. Что-то не так с кодом где-то? IE10 неправильно реализует спецификацию CORS, игнорируя порт # при определении, является ли это запросом перекрестного происхождения? DoNotTrack по умолчанию ENABLED как-то связано с этим? Я мог бы поклясться, что у меня это работало нормально на днях... Любое понимание этого будет с благодарностью. Заранее спасибо. Кстати, я знаю, что мог бы использовать async / await, за исключением того факта, что я не могу, потому что на работе мы все еще на Windows Server 2003 >.<

0 ответов

Другие вопросы по тегам