Получение 400 неверных запросов при использовании multipart / form-data в качестве Content-Type в XHR - PullRequest
3 голосов
/ 23 января 2011

У меня есть запрос AJAX, который отправляет некоторые данные. Данные соответствуют multipart / form-data спецификация .

Проблема, с которой я сталкиваюсь, заключается в том, что браузер устанавливает заголовок Content-Type на text / plain, и он должен быть multipart / form-data.

Я пытался сделать это: request.setRequestHeader("Content-Type", "multipart/form-data");, но это выдает ошибку 400 Bad Request.

Если я сделаю request.setRequestHeader("Content-Typexxxx", "multipart/form-data");, ошибки не возникнет, заголовок «Content-Typexxxx» будет установлен, но, очевидно, он мне не поможет.

Я предполагаю, что есть список допустимых заголовков Content-Type, которые можно установить, и «multipart / form-data» среди них нет, но я не могу найти решение моей проблемы.

Пример фактически отправляемых данных:

Content-Type: multipart/form-data; boundary=l3iPy71otz

--l3iPy71otz
Content-Disposition: form-data; name="titluPublic"

Variation_1
--l3iPy71otz
Content-Disposition: form-data; name="nr_versiune"


--l3iPy71otz--

Спасибо!

1 Ответ

4 голосов
/ 23 января 2011

Вы не установили boundary в заголовке запроса, например:

request.setRequestHeader("Content-Type", "multipart/form-data; boundary=l3iPy71otz");

Для получения дополнительной информации см. RFC 2045 :

5 Поле заголовка типа контента
[…]
Параметры являются модификаторами медиа подтипа и, как таковые, не оказывают существенного влияния на природу контента.Набор значимых параметров зависит от типа и подтипа носителя.Большинство параметров связаны с одним конкретным подтипом.Однако данный тип носителя верхнего уровня может определять параметры, которые применимы к любому подтипу этого типа.Параметры могут требоваться по их определению типа или подтипа контента или могут быть необязательными.Реализации MIME должны игнорировать любые параметры, имена которых они не распознают.

Например, параметр "charset" применим к любому подтипу "text", в то время как параметр "border" требуется для любогоподтип мультимедийного типа «multipart».

Обновление: Другая найденная проблема в сети появляется при добавлении charsetдо Content-type в заголовке запроса, но не в границах сообщения в теле (это также верно для вашего тестового примера).Это не кажется вероятным решением, но, возможно, это поможет.

В вашем случае явно добавьте charset как в заголовок запроса, так и в границы сообщения:

data.params += "--" + data.uniqid + "; charset=UTF-8" + data.crlf;
…
request.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + data.uniqid + "; charset=UTF-8");

Обновление 2: Попробовав это самостоятельно, я заметил, что начальная граница не распознается как таковая, а интерпретируется как содержимое последнего параметра (на моем более щадящем сервере).Возможно, это приводило к тому, что Apache выдавал ошибку 400 Bad Request.

После некоторых проб и ошибок я заметил, что это было вызвано тем, что сервер ожидал, что charset будет находиться в на каждой границе.даже последний.Чтобы избежать путаницы, я решил явно установить charset в заголовке запроса перед параметром границы, чтобы граница была последним параметром в заголовке запроса Content-type.После этого все, казалось, работало нормально.

data.params = "Content-Type: multipart/form-data; boundary=" + data.uniqid;
…
data.params += "--" + data.uniqid + data.crlf;
…
data.params += "--" + data.uniqid + "--";
…
request.setRequestHeader("Content-Type", "multipart/form-data; charset=UTF-8; boundary=" + data.uniqid);
...