Есть ли разница в определении 'Content-type' в XMLHttpRequest?

Я обычно отправляю ajax'ом данные в виде json строки и Content-type значение устанавливал application/json. Однако сейчас я делаю кросдомменный ajax запрос с помощью CORS и мне выдается ошибка. Оказывается CORS не поддерживает application/json:

The only allowed values for the Content-Type header are:
 -application/x-www-form-urlencoded
 -multipart/form-data
 -text/plain

Но интересно то, что данные доходят до сервера, несмотря на то, что я указал Content-type - application/x-www-form-urlencoded.

Вот мой ajax запрос:

const form = document.getElementById('contact_form');
form.addEventListener('submit', function(e) {
  e.preventDefault();
  const send = {
    name: document.querySelector('input[name=name]').value,
    email: document.querySelector('input[name=email]').value,
    subject: document.querySelector('input[name=subject]').value,
    message: document.querySelector('textarea[name=message]').value
  };
  const jsonString = JSON.stringify(send);
  const xhr = new XMLHttpRequest();
  const action = form.getAttribute('action');
  xhr.open('POST', action, true);
  xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  xhr.onload = function() {
        if (this.readyState == 4 && this.status == 200) {
         alert(xhr.responseText);
       }else{
         alert(xhr.responseText);
       };
    };
  xhr.send(jsonString);
});

И поэтому меня интересует вопрос, есть ли разница какой Content-type выбрать и что из вышеперечисленного доступного мне лучше выбрать или возможно есть еще какие то альтернативы?


Ответы (1 шт):

Автор решения: Pavel Grishaev

Это просто разные форма формирования тела HTTP-запроса. Это универсальное поведение работать будет там, где сервер это не ограничивает. Если на сервере у API жёстко ограничен тип, то так отправить будет не возможно.

Выбирать тип нужно по его назначению.

application/x-www-form-urlencoded - кодирует переменные в виде строки URL. Картинку например так кодировать в символы не разумно. Для передачи готовой строки json приемлемо, но избыточно. А вместо json - так будет передача только одного уровня вложенности переменных, то есть только первых ключей объекта, или будут какие-то хитрые манипуляции с переименованием ключей.

multipart/form-data - служит для запросов с различными вложенными данными. Например переменные + картинки, или несколько картинок. Для передачи готовой строки json приемлемо, но избыточно. А вместо json то же, что на прошлом пункте.

text/plain - просто текст. Картинку так отправлять можно, но придётся кодировать самому. Для передачи готовой строки json хорошо. Вместо json не возможно - здесь нет переменных, это просто сплошной текст.

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

→ Ссылка