Подтвердить что ты не робот

Запрос CORS предваряется, но похоже, что это не должно быть

Предусматривается следующий запрос POST для перекрестного происхождения с типом содержимого типа multipart/form-data и только простых заголовков. Согласно спецификации W3C, если я не читаю ее неправильно, ее не следует предусматривать. Я подтвердил, что это происходит в Chrome 27 и Firefox 10.8.3. Я не тестировал другие браузеры.

Вот заголовки запросов и т.д.:

Request URL:http://192.168.130.135:8081/upload/receiver
Request Method:POST
Status Code:200 OK
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:27129
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryix5VzTyVtCMwcNv6
Host:192.168.130.135:8081
Origin:http://192.168.130.135:8080
Referer:http://192.168.130.135:8080/test/raytest-jquery.html
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.37 Safari/537.36

И вот запрос OPTIONS (предполетный):

Request URL:http://192.168.130.135:8081/upload/receiver
Request Method:OPTIONS
Status Code:200 OK
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:origin, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:192.168.130.135:8081
Origin:http://192.168.130.135:8080
Referer:http://192.168.130.135:8080/test/raytest-jquery.html
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.37 Safari/537.36

Спектр кажется довольно ясным:

UPDATE: Вот несколько простых клиентских кодов, которые будут воспроизводить это:

var xhr = new XMLHttpRequest(),
    formData = new FormData();

formData.append('myfile', someFileObj);

xhr.upload.progress = function(e) {
    //insert upload progress logic here
};

xhr.open('POST', 'http://192.168.130.135:8080/upload/receiver', true);
xhr.send(formData);

Кто-нибудь знает, почему это предваряется?

4b9b3361

Ответ 1

В результате я выяснил исходный код Webkit, пытаясь понять это (после того, как Google не дал никаких полезных ударов). Оказывается, Webkit будет принудительно запрограммировать любой запрос перекрестного происхождения, если вы зарегистрируете обработчик события onprogress. Я не совсем уверен, даже после прочтения комментариев кода, почему эта логика была применена.

В XMLHttpRequest.cpp:

void XMLHttpRequest::createRequest(ExceptionCode& ec)
{
    ...

    options.preflightPolicy = uploadEvents ? ForcePreflight : ConsiderPreflight;

    ...

    // The presence of upload event listeners forces us to use preflighting because POSTing to an URL that does not
    // permit cross origin requests should look exactly like POSTing to an URL that does not respond at all.
    // Also, only async requests support upload progress events.
    bool uploadEvents = false;
    if (m_async) {
        m_progressEventThrottle.dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().loadstartEvent));
        if (m_requestEntityBody && m_upload) {
            uploadEvents = m_upload->hasEventListeners();
            m_upload->dispatchEvent(XMLHttpRequestProgressEvent::create(eventNames().loadstartEvent));
        }
    }

    ...
}


ОБНОВЛЕНИЕ: Firefox применяет ту же логику, что и Webkit. Вот соответствующий код из nsXMLHttpRequest.cpp:

nsresult
nsXMLHttpRequest::CheckChannelForCrossSiteRequest(nsIChannel* aChannel)
{
    ...

    // Check if we need to do a preflight request.
    nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
    NS_ENSURE_TRUE(httpChannel, NS_ERROR_DOM_BAD_URI);

    nsAutoCString method;
    httpChannel->GetRequestMethod(method);
    if (!mCORSUnsafeHeaders.IsEmpty() ||
        (mUpload && mUpload->HasListeners()) ||
        (!method.LowerCaseEqualsLiteral("get") &&
         !method.LowerCaseEqualsLiteral("post") &&
         !method.LowerCaseEqualsLiteral("head"))) {
      mState |= XML_HTTP_REQUEST_NEED_AC_PREFLIGHT;
    }

    ...
}

Обратите внимание на mUpload && mUpload->HasListeners() часть условного выражения.

Похоже, что Webkit и Firefox (и, возможно, другие) вставили некоторую логику в свой код предпросмотра, который не был санкционирован спецификацией W3C. Если мне не хватает чего-то в спецификации, прокомментируйте.

Ответ 2

Я предполагаю, что "граница" в заголовке Content-Type вызывает проблемы. Если вы можете воспроизвести это, оно должно быть зарегистрировано как ошибка браузера, поскольку спецификация указывает, что проверка заголовка Content-Type должна исключать параметры.