Sunday, January 27, 2019

CookiePad

h – coffeemakr 15 'mm

Stack Overflow
sign up log in
By using our site, you acknowledge that you have read and understand our Cookie Policy, Privacy Policy, and our Terms of Service.
Questions Jobs Tags Users Badges Ask
up vote
423
down vote
favorite
Send POST data using XMLHttpRequest
javascript ajax post xmlhttprequest
I'd like to send some data using an XMLHttpRequest in JavaScript.

Say I have the following form in 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>
How can I write the equivalent using an XMLHttpRequest in JavaScript?
share improve this question
asked
Mar 15 '12 at 2:09

Jack Greenhill
3,989●10●33●61 edited
Sep 12 '16 at 13:56

T.Todua
30.2k●12●132●131

8 Answers
order by
up vote
602
down vote
accepted
The code below demonstrates on how to do this.

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);
share improve this answer
answered
Mar 15 '12 at 2:12

Ed Heal
47.8k●13●65●105 edited
May 25 '18 at 6:34

36
Is it possible to send an object in params instead of a string like in jQuery? – Vadorequest Sep 7 '14 at 11:27
4
No, but @Vadorequest's comment mentioned jQuery - he asked if it were possible to pass data "like jQuery". I mentioned how I think jQuery does it and thus, how you could achieve this. – Dan Pantry Apr 16 '15 at 14:33
10
@EdHeal, Connection and Content-Length headers cannot be set. It'll say "Refused to set unsafe header "content-length"" . See stackoverflow.com/a/2624167/632951 – Pacerier Jun 27 '15 at 10:55
49
Note: setRequestHeader() after open(). Took me an hour, let's hope this comment saves someone an hour ;) – Kevin Sep 26 '16 at 8:30
4
is it possible to send an application/json request? – Dev Dec 6 '16 at 3:03
show 9 more comments
up vote
221
down vote
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');
Or if you can count on browser support you could use FormData:

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);
share improve this answer
answered
Mar 9 '13 at 16:21

uKolka
16.1k●4●25●40 edited
Jun 24 '13 at 13:43

1
FormData takes the form element as its constructor argument, no need to add values indivually – Juan Mendes Jun 22 '13 at 5:51
4
Yes, but question was to write JavaScript equivalent of provided form not submit the form using JavaScript. – uKolka Jun 22 '13 at 17:07
3
The answer that has few votes but got marked correct uses two extra headers: http.setRequestHeader("Content-length", params.length); and http.setRequestHeader("Connection", "close");. Are they needed? Are they perhaps only needed on certain browsers? (There is a comment on that other page saying setting the Content-Length header was "exactly what was needed") – Darren Cook Oct 17 '13 at 0:19
@Darren Cook Implementation dependent. From my experience major browsers set 'Content-length' (it is required) automatically from the data you supply. 'Connection' header defaults to 'keep-alive' in most cases, which keeps connection open for a while so subsequent requests don't have to reestablish connection again as in case of 'close'. You can try those snippets in the console, using current page URL and inspect request headers using browser's tools or wireshark. – uKolka Oct 18 '13 at 0:46
2
@uKolka it should be noted on the reply than with your second solution the request Content-Type changes automatically to multipart/form-data. This has serious implications on the server side and how the information is accessed there. – AxeEffect Jul 10 '17 at 9:29
show 2 more comments
up vote
38
down vote
Use modern JavaScript!

I'd suggest looking into fetch. It is the ES5 equivalent and uses Promises. It is much more readable and easily customizable.

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)
);
More Info:

Mozilla Documentation

Can I Use (88% Mar 2018)

Matt Walsh Tutorial
share improve this answer
answered
Aug 6 '17 at 7:14

Gibolt
5,212●2●47●40 edited
Apr 21 '18 at 23:35

1
You should avoid using Promises and fat arrows for things this critical to webpage functionality, as many devices do not have browsers that support these features. – Dmitry Sep 2 '17 at 13:30
5
Promises are 90% covered. I added function() examples in case you don't prefer =>. You should absolutely be using modern JS to ease the developer experience. Worrying about a small percentage of people stuck on IE isn't worth it unless you are a huge enterprise – Gibolt Sep 2 '17 at 20:06
4
Fat arrow also doesn't work with this keyword. I like to mention that, but I also secretly hate people that use this, and inheritance architecture instead of function factories. Forgive me, I am node. – agm1984 Sep 8 '17 at 9:17
2
I avoid this like the plague as well, and so should anyone reading this. – Gibolt Oct 20 '17 at 17:28
1
If worried about compatibility...Google es6 transpiler... stackoverflow.com/questions/40205547/…. Write it simple. Deploy it compatible. +1 avoid this. – TamusJRoyce Dec 27 '17 at 17:25
show 2 more comments
up vote
31
down vote
Minimal use of FormData to submit an AJAX request

<!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>
Remarks

This does not fully answer the OP question because it requires the user to click in order to submit the request. But this may be useful to people searching for this kind of simple solution.
This example is very simple and does not support the GET method. If you are interesting by more sophisticated examples, please have a look at the excellent MDN documentation. See also similar answer about XMLHttpRequest to Post HTML Form.
Limitation of this solution: As pointed out by Justin Blank and Thomas Munk (see their comments), FormData is not supported by IE9 and lower, and default browser on Android 2.3.
share improve this answer
answered
Nov 7 '13 at 14:17

olibre
26.7k●16●113●150 edited
Jan 5 '18 at 5:54

rogerdpack
34k●15●129●252
1
The only thing about this is that I think FormData is not available in IE 9, so it's not going to be usable for a lot of people without a polyfill. developer.mozilla.org/en-US/docs/Web/API/FormData – Justin Blank Jul 9 '14 at 14:19
1
Correct with IE9: caniuse.com/#search=FormData – Thomas Munk Oct 23 '14 at 19:08
2
Elegant solution, but you should specify onsubmit="return submitForm(this);" otherwise the user gets redirected to the URL in the request. – Vic Feb 9 '15 at 13:28
1
I'm not that experienced with web-development. I've figured out that the POST request is indeed sent when you return false. If true is returned, the original (unwanted) POST request will be send! Your answer is correct, sorry for the confusion. – Markus L Jun 21 '17 at 7:06
1
works somewhat in IE11 apparently, FWIW... – rogerdpack Jan 5 '18 at 5:57
show 4 more comments
up vote
22
down vote
NO PLUGINS NEEDED!

Just drag any link (i.e. THIS LINK) in BOOKMARK BAR (if you dont see it, enable from Browser Settings), then EDIT that link :

enter image description here

and insert javascript code:

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);
That's all! Now you can visit any website, and click that button in BOOKMARK BAR!

NOTE:

The above method sends data using XMLHttpRequest method, so, you have to be on the same domain while triggering the script. That's why I prefer sending data with a simulated FORM SUBMITTING, which can send the code to any domain - here is code for that:

 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);
share improve this answer
answered
Jul 28 '16 at 17:35

T.Todua
30.2k●12●132●131 edited
Nov 18 '17 at 8:28

For Mozilla, Can I do something similar to this? – user6538026 Jul 29 '16 at 5:46
I didn't and I couldn't :| I don't have 125 reps :| And if you see my profile you will see I have 136 up votes :| Even after I get the permission to downvote, I will avoid it unless it is neccessary :| – user6538026 Jul 29 '16 at 9:20
15
And your question really doesn't answer what OP has asked for. BookMarking a HTTP Request... !? I don't see any point relating XmlHttpRequest in your answer :| – user6538026 Jul 29 '16 at 9:27
@Iceman i wont start arguing with you about the profitability of my answer. however, i have updated my answer, and now there is what you wanted. – T.Todua Aug 19 '16 at 11:01
2
awesome. just wanted some relation while reviewing since it was an answer . now it is an answer plus a gr8 tip for all who drop by. i've reverted votes. cheers – Iceman Aug 19 '16 at 11:06
add a comment
up vote
19
down vote
Here is a complete solution with 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>
Ensure that your Backend API can parse JSON.

For example, in Express JS:

import bodyParser from 'body-parser'
app.use(bodyParser.json())
share improve this answer
answered
Sep 8 '17 at 9:11

agm1984
3,619●1●17●35 edited
Apr 17 '18 at 19:10

1
Great, but don't use 'false' value for the async parameter in XMLHttpRequest.open - it's deprecated and will give a warning – johnnycardy Mar 23 '18 at 15:29
Should we put true there or just omit that parameter? I will update the answer if you can specify which is preferable. – agm1984 Apr 16 '18 at 19:56
1
It should default to true but I don't know if all browsers respect that – johnnycardy Apr 17 '18 at 8:58
Given the default of true, I am going to remove it from the example and drop this URL for research: developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open – agm1984 Apr 17 '18 at 19:09
I like that better because it's reasonable and one less detail for someone to start with. Thanks for highlighting it. – agm1984 Apr 17 '18 at 19:11
add a comment
up vote
4
down vote
I have faced similar problem, using the same post and and this link I have resolved my issue.

 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);
This link has completed information.
share improve this answer
answered
Sep 26 '16 at 13:12

Laxman G
1,340●2●19●36 edited
Feb 23 '18 at 10:39

up vote
2
down vote
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");
}
share improve this answer
answered
Jul 2 '16 at 1:57

toto
603●2●7●22 edited
Dec 8 '16 at 16:46

1
Could you explain this code a bit ? – Hugo Nava Kopp Dec 8 '16 at 15:38
1
Hello Hugo, This code is to send data or file with progress upload if browser support it. included all possible events and compatibility browser. It try use the most new object class from browser. It help you? – toto Dec 8 '16 at 17:24
add a comment
meta chat tour help blog privacy policy legal contact us full site
Download the Stack Exchange Android app
2019 Stack Exchange, Inc

No comments:

Post a Comment