Отправка POST-данных с использованием XMLHttpRequest

393

Я хотел бы отправить некоторые данные с помощью XMLHttpRequest в JavaScript.

Скажем, у меня есть следующая форма в HTML:

<form name="inputform" action="somewhere" method="post">
    <input type="hidden" value="person" name="user">
    <input type="hidden" value="password" name="pwd">
    <input type="hidden" value="place" name="organization">
    <input type="hidden" value="key" name="requiredkey">
</form>

Как написать эквивалент, используя XMLHttpRequest в JavaScript?

Теги:
xmlhttprequest
post

8 ответов

543
Лучший ответ

В приведенном ниже коде показано, как это сделать.

var http = new XMLHttpRequest();
var url = 'get_data.php';
var params = 'orem=ipsum&name=binny';
http.open('POST', url, true);

//Send the proper header information along with the request
http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

http.onreadystatechange = function() {//Call a function when the state changes.
    if(http.readyState == 4 && http.status == 200) {
        alert(http.responseText);
    }
}
http.send(params);
  • 37
    Можно ли отправить объект в params вместо строки, как в jQuery?
  • 1
    Поправьте меня, если я ошибаюсь, но разве jquery не просто кодирует объект в серию пар ключ-значение? Вы всегда можете кодировать объект base64, хотя это может привести к громоздким URL
Показать ещё 12 комментариев
203
var xhr = new XMLHttpRequest();
xhr.open('POST', 'somewhere', true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.onload = function () {
    // do something to response
    console.log(this.responseText);
};
xhr.send('user=person&pwd=password&organization=place&requiredkey=key');

Или, если вы можете рассчитывать на поддержку браузера, вы можете использовать FormData​​strong > :

var data = new FormData();
data.append('user', 'person');
data.append('pwd', 'password');
data.append('organization', 'place');
data.append('requiredkey', 'key');

var xhr = new XMLHttpRequest();
xhr.open('POST', 'somewhere', true);
xhr.onload = function () {
    // do something to response
    console.log(this.responseText);
};
xhr.send(data);
  • 1
    FormData принимает элемент формы в качестве аргумента конструктора, нет необходимости добавлять значения по отдельности
  • 4
    Да, но вопрос заключался в написании JavaScript-эквивалента предоставленной формы, а не в отправке формы с использованием JavaScript.
Показать ещё 5 комментариев
29

Минимальное использование FormData для отправки запроса AJAX

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge, chrome=1"/>
<script>
"use strict";
function submitForm(oFormElement)
{
  var xhr = new XMLHttpRequest();
  xhr.onload = function(){ alert (xhr.responseText); } // success case
  xhr.onerror = function(){ alert (xhr.responseText); } // failure case
  xhr.open (oFormElement.method, oFormElement.action, true);
  xhr.send (new FormData (oFormElement));
  return false;
}
</script>
</head>

<body>
<form method="post" action="somewhere" onsubmit="return submitForm(this);">
  <input type="hidden" value="person"   name="user" />
  <input type="hidden" value="password" name="pwd" />
  <input type="hidden" value="place"    name="organization" />
  <input type="hidden" value="key"      name="requiredkey" />
  <input type="submit" value="post request"/>
</form>
</body>
</html>

замечания

  1. Это не полностью отвечает на вопрос OP, потому что для запроса запроса пользователю требуется щелкнуть. Но это может быть полезно людям, которые ищут такое простое решение.

  2. Этот пример очень прост и не поддерживает метод GET. Если вам интересны более сложные примеры, ознакомьтесь с отличной документацией MDN. См. Также аналогичный ответ о XMLHttpRequest для отправки HTML-формы.

  3. Ограничение этого решения: Как отметили Джастин Бланк и Томас Манк (см. Их комментарии), FormData не поддерживается IE9 и ниже, а браузер по умолчанию на Android 2.3.

  • 1
    Единственное, что я думаю об этом, это то, что я думаю, что FormData недоступен в IE 9, поэтому он не будет пригоден для использования многими людьми без полизаполнения. developer.mozilla.org/en-US/docs/Web/API/FormData
  • 1
    Исправьте с IE9: caniuse.com/#search=FormData
Показать ещё 7 комментариев
28

Используйте современный JavaScript!

Я бы предложил заглянуть в fetch. Это эквивалент ES5 и использует Promises. Это гораздо более читаемо и легко настраивается.

const url = "http://example.com";
fetch(url, {
    method : "POST",
    body: new FormData(document.getElementById("inputform")),
    // -- or --
    // body : JSON.stringify({
        // user : document.getElementById('user').value,
        // ...
    // })
}).then(
    response => response.text() // .json(), etc.
    // same as function(response) {return response.text();}
).then(
    html => console.log(html)
);

Больше информации:

Документация Mozilla

Могу ли я использовать (88% март 2018 года)

Учебник Мэтта Уолша

  • 2
    Вы должны избегать использования Обещаний и жирных стрелок для вещей, которые имеют решающее значение для функциональности веб-страницы, так как многие устройства не имеют браузеров, которые поддерживают эти функции.
  • 5
    Обещания покрыты на 90%. Я добавил примеры function() если вы не предпочитаете => . Вы должны абсолютно использовать современный JS, чтобы облегчить опыт разработчика. Беспокойство о небольшом проценте людей, застрявших в IE, не стоит того, если вы не большое предприятие
Показать ещё 5 комментариев
23

НЕТ НЕСКОЛЬКИХ ПЛОЩАДЕЙ!

Просто перетащите любую ссылку (т.е. ЭТА ССЫЛКА) в BOOKMARK BAR ( если вы его не видите, включите параметры браузера), затем ИЗМЕНИТЬ, что ссылка:

Изображение 3591

и вставьте код javascript:

javascript:var my_params = prompt("Enter your parameters", "var1=aaaa&var2=bbbbb"); var Target_LINK = prompt("Enter destination", location.href); function post(path, params) { var xForm = document.createElement("form"); xForm.setAttribute("method", "post"); xForm.setAttribute("action", path); for (var key in params) { if (params.hasOwnProperty(key)) { var hiddenField = document.createElement("input"); hiddenField.setAttribute("name", key); hiddenField.setAttribute("value", params[key]); xForm.appendChild(hiddenField); } } var xhr = new XMLHttpRequest(); xhr.onload = function () { alert(xhr.responseText); }; xhr.open(xForm.method, xForm.action, true); xhr.send(new FormData(xForm)); return false; } parsed_params = {}; my_params.split("&").forEach(function (item) { var s = item.split("="), k = s[0], v = s[1]; parsed_params[k] = v; }); post(Target_LINK, parsed_params); void(0);

Что все! Теперь вы можете посетить любой сайт и нажать эту кнопку в BOOKMARK BAR!


Примечание:

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

 javascript:var my_params=prompt("Enter your parameters","var1=aaaa&var2=bbbbb"); var Target_LINK=prompt("Enter destination", location.href); function post(path, params) {   var xForm= document.createElement("form");   xForm.setAttribute("method", "post");   xForm.setAttribute("action", path); xForm.setAttribute("target", "_blank");   for(var key in params) {   if(params.hasOwnProperty(key)) {        var hiddenField = document.createElement("input");      hiddenField.setAttribute("name", key);      hiddenField.setAttribute("value", params[key]);         xForm.appendChild(hiddenField);     }   }   document.body.appendChild(xForm);  xForm.submit(); }   parsed_params={}; my_params.split("&").forEach(function(item) {var s = item.split("="), k=s[0], v=s[1]; parsed_params[k] = v;}); post(Target_LINK, parsed_params); void(0); 
  • 0
    Для Mozilla, могу ли я сделать что-то похожее на это?
  • 0
    Я не сделал и не мог: | У меня нет 125 повторений: | И если вы увидите мой профиль, то увидите, что я набрал 136 голосов: | Даже после того, как я получу разрешение понизить голосование, я буду избегать его, если это не будет необходимо: |
Показать ещё 3 комментария
13

Вот полное решение с application-json:

// Input values will be grabbed by ID
<input id="loginEmail" type="text" name="email" placeholder="Email">
<input id="loginPassword" type="password" name="password" placeholder="Password">

// return stops normal action and runs login()
<button onclick="return login()">Submit</button>

<script>
    function login() {
        // Form fields, see IDs above
        const params = {
            email: document.querySelector('#loginEmail').value,
            password: document.querySelector('#loginPassword').value
        }

        const http = new XMLHttpRequest()
        http.open('POST', '/login')
        http.setRequestHeader('Content-type', 'application/json')
        http.send(JSON.stringify(params)) // Make sure to stringify
        http.onload = function() {
            // Do whatever with response
            alert(http.responseText)
        }
    }
</script>

Убедитесь, что ваш API Backend может анализировать JSON.

Например, в Express JS:

import bodyParser from 'body-parser'
app.use(bodyParser.json())
  • 1
    Отлично, но не используйте значение false для параметра async в XMLHttpRequest.open - он устарел и выдаст предупреждение
  • 0
    Должны ли мы поставить true или просто пропустить этот параметр? Я буду обновлять ответ, если вы можете указать, что является предпочтительным.
Показать ещё 3 комментария
3

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

 var http = new XMLHttpRequest();
 var url = "MY_URL.Com/login.aspx";
 var params = 'eid=' +userEmailId+'&amp;pwd='+userPwd

 http.open("POST", url, true);

 // Send the proper header information along with the request
 //http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
 //http.setRequestHeader("Content-Length", params.length);// all browser wont support Refused to set unsafe header "Content-Length"
 //http.setRequestHeader("Connection", "close");//Refused to set unsafe header "Connection"

 // Call a function when the state 
 http.onreadystatechange = function() {
    if(http.readyState == 4 && http.status == 200) {
        alert(http.responseText);
    }
 }
 http.send(params);

Эта ссылка завершена.

2
var util = {
    getAttribute: function (dom, attr) {
        if (dom.getAttribute !== undefined) {
            return dom.getAttribute(attr);
        } else if (dom[attr] !== undefined) {
            return dom[attr];
        } else {
            return null;
        }
    },
    addEvent: function (obj, evtName, func) {
        //Primero revisar attributos si existe o no.
        if (obj.addEventListener) {
            obj.addEventListener(evtName, func, false);

        } else if (obj.attachEvent) {
            obj.attachEvent(evtName, func);
        } else {
            if (this.getAttribute("on" + evtName) !== undefined) {
                obj["on" + evtName] = func;
            } else {
                obj[evtName] = func;
            }

        }

    },
    removeEvent: function (obj, evtName, func) {
        if (obj.removeEventListener) {
            obj.removeEventListener(evtName, func, false);
        } else if (obj.detachEvent) {
            obj.detachEvent(evtName, func);
        } else {
            if (this.getAttribute("on" + evtName) !== undefined) {
                obj["on" + evtName] = null;
            } else {
                obj[evtName] = null;
            }
        }

    },
    getAjaxObject: function () {
        var xhttp = null;
        //XDomainRequest
        if ("XMLHttpRequest" in window) {
            xhttp = new XMLHttpRequest();
        } else {
            // code for IE6, IE5
            xhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        return xhttp;
    }

};

//START CODE HERE.

var xhr = util.getAjaxObject();

var isUpload = (xhr && ('upload' in xhr) && ('onprogress' in xhr.upload));

if (isUpload) {
    util.addEvent(xhr, "progress", xhrEvt.onProgress());
    util.addEvent(xhr, "loadstart", xhrEvt.onLoadStart);
    util.addEvent(xhr, "abort", xhrEvt.onAbort);
}

util.addEvent(xhr, "readystatechange", xhrEvt.ajaxOnReadyState);

var xhrEvt = {
    onProgress: function (e) {
        if (e.lengthComputable) {
            //Loaded bytes.
            var cLoaded = e.loaded;
        }
    },
    onLoadStart: function () {
    },
    onAbort: function () {
    },
    onReadyState: function () {
        var state = xhr.readyState;
        var httpStatus = xhr.status;

        if (state === 4 && httpStatus === 200) {
            //Completed success.
            var data = xhr.responseText;
        }

    }
};
//CONTINUE YOUR CODE HERE.
xhr.open('POST', 'mypage.php', true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');


if ('FormData' in window) {
    var formData = new FormData();
    formData.append("user", "aaaaa");
    formData.append("pass", "bbbbb");

    xhr.send(formData);

} else {

    xhr.send("?user=aaaaa&pass=bbbbb");
}
  • 1
    Не могли бы вы немного объяснить этот код?
  • 1
    Здравствуйте, Хьюго! Этот код предназначен для отправки данных или файлов с загрузкой, если браузер поддерживает это. включены все возможные события и совместимость браузера. Он пытается использовать самый новый класс объектов из браузера. Вам это поможет?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню