Is there a way to send data using the POST method without a form and without refreshing the page using only pure JavaScript (not jQuery $.post()
)? Maybe httprequest
or something else (just can't find it now)?

- 27,532
- 16
- 147
- 165

- 7,500
- 16
- 62
- 95
-
4XMLHttpRequest is the answer ...$.post uses the same under the hood. – Chandu Jun 18 '11 at 12:48
-
This question can help you: [https://stackoverflow.com/questions/58217910/xmlhttprequest-not-sending-post-data/58218057][1] [1]: https://stackoverflow.com/questions/58217910/xmlhttprequest-not-sending-post-data/58218057 – Jorge del Campo Andrade Oct 03 '19 at 18:05
13 Answers
You can send it and insert the data to the body:
var xhr = new XMLHttpRequest();
xhr.open("POST", yourUrl, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({
value: value
}));
By the way, for get request:
var xhr = new XMLHttpRequest();
// we defined the xhr
xhr.onreadystatechange = function () {
if (this.readyState != 4) return;
if (this.status == 200) {
var data = JSON.parse(this.responseText);
// we get the returned data
}
// end of state change: it can be after some time (async)
};
xhr.open('GET', yourUrl, true);
xhr.send();

- 2,967
- 1
- 9
- 3
-
4
-
6@Hylle async: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open – BlackICE Dec 20 '18 at 18:10
-
3This is the old way of doing requests. I highly recommend not using this method and use `fetch` function instead. – Michael Artman Nov 12 '21 at 17:46
-
Here is a tutorial on this topic from the MDN pages: https://developer.mozilla.org/en-US/docs/Learn/Forms/Sending_forms_through_JavaScript – nuiun Sep 02 '22 at 09:47
-
@MichaelArtman Which is even today, more then a year after your comment not supported in all browsers. – IgorR Jan 02 '23 at 10:37
-
@IgorR https://caniuse.com/fetch ~99% of the browser market share does have it. – Michael Artman Jan 04 '23 at 12:58
-
@MichaelArtman It says 95.96% market share on the exact page you linked which means 1 in 20 people will have a non-functional application. – IgorR Jan 11 '23 at 12:19
-
@IgorR technically, it's closer to 1/25, and that one person knows they are using an older browser that most websites don't work with. Each year that percentage grows closer to 100%, so `fetch` is the correct choice. – Michael Artman Jan 12 '23 at 16:47
-
can you pls expand this answer to show code for handling success response and error response (or if its the same and we have to check the status code then that) – Nikhil VJ Feb 09 '23 at 09:47
The Fetch API is intended to make GET requests easy, but it is able to POST as well.
let data = {element: "barium"};
fetch("/post/data/here", {
method: "POST",
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data)
}).then(res => {
console.log("Request complete! response:", res);
});
If you are as lazy as me (or just prefer a shortcut/helper):
window.post = function(url, data) {
return fetch(url, {method: "POST", headers: {'Content-Type': 'application/json'}, body: JSON.stringify(data)});
}
// ...
post("post/data/here", {element: "osmium"});

- 13,019
- 9
- 47
- 86

- 4,692
- 1
- 14
- 19
-
4Because of this answer's simplicity, I upvoted it prematurely and it doesn't allow me to retract my vote. Sending data only works if you add headers. (headers: {'Accept': 'application/json', 'Content-Type': 'application/json'}) Furthermore, receiving data doesn't work either unless you call the json() method on the response, like this: res.json(), which happens to return yet another promise that you have to unwrap. Best to use async/await and unwrap all of these promises with await. – OCDev Jun 02 '21 at 03:28
-
1
-
-
Direct link to fetch function parameters documentation https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters – Nico Bako Apr 20 '22 at 21:57
-
i used this technique. It somehow solved my problem but i went crazy when chrome developer's tool stopped showing response body. I thought it was an issue with my api. After hours of debugging, i got to know this is an issue with fetch api. Once you return res.json(), developer's tool started to show the response. I wish i had spent my friday night doing something more productive :( – Manish Bansal Sep 23 '22 at 16:00
You can use the XMLHttpRequest
object as follows:
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
xhr.send(someStuff);
That code would post someStuff
to url
. Just make sure that when you create your XMLHttpRequest
object, it will be cross-browser compatible. There are endless examples out there of how to do that.

- 164,175
- 21
- 332
- 312
-
3
-
7
-
1That's a good answer, and `someStuff` can be anything you want even a simple string. you can check the request using online services such as my personal favorite: (https://requestb.in) – JamesC Nov 20 '17 at 18:04
-
the `application/x-www-form-urlencoded` MIME type doesn't have a `charset` parameter: https://www.iana.org/assignments/media-types/application/x-www-form-urlencoded – jbg Oct 28 '19 at 17:35
-
the someStuff var would usually want to be set as "variable=value". Then you can retrieve the data with $_POST['variable'], this will be equal too the 'value' – Rhys Broughton Apr 04 '22 at 23:47
Also, RESTful lets you get data back from a POST request.
JS (put in static/hello.html to serve via Python):
<html><head><meta charset="utf-8"/></head><body>
Hello.
<script>
var xhr = new XMLHttpRequest();
xhr.open("POST", "/postman", true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({
value: 'value'
}));
xhr.onload = function() {
console.log("HELLO")
console.log(this.responseText);
var data = JSON.parse(this.responseText);
console.log(data);
}
</script></body></html>
Python server (for testing):
import time, threading, socket, SocketServer, BaseHTTPServer
import os, traceback, sys, json
log_lock = threading.Lock()
log_next_thread_id = 0
# Local log functiondef
def Log(module, msg):
with log_lock:
thread = threading.current_thread().__name__
msg = "%s %s: %s" % (module, thread, msg)
sys.stderr.write(msg + '\n')
def Log_Traceback():
t = traceback.format_exc().strip('\n').split('\n')
if ', in ' in t[-3]:
t[-3] = t[-3].replace(', in','\n***\n*** In') + '(...):'
t[-2] += '\n***'
err = '\n*** '.join(t[-3:]).replace('"','').replace(' File ', '')
err = err.replace(', line',':')
Log("Traceback", '\n'.join(t[:-3]) + '\n\n\n***\n*** ' + err + '\n***\n\n')
os._exit(4)
def Set_Thread_Label(s):
global log_next_thread_id
with log_lock:
threading.current_thread().__name__ = "%d%s" \
% (log_next_thread_id, s)
log_next_thread_id += 1
class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
Set_Thread_Label(self.path + "[get]")
try:
Log("HTTP", "PATH='%s'" % self.path)
with open('static' + self.path) as f:
data = f.read()
Log("Static", "DATA='%s'" % data)
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
self.wfile.write(data)
except:
Log_Traceback()
def do_POST(self):
Set_Thread_Label(self.path + "[post]")
try:
length = int(self.headers.getheader('content-length'))
req = self.rfile.read(length)
Log("HTTP", "PATH='%s'" % self.path)
Log("URL", "request data = %s" % req)
req = json.loads(req)
response = {'req': req}
response = json.dumps(response)
Log("URL", "response data = %s" % response)
self.send_response(200)
self.send_header("Content-type", "application/json")
self.send_header("content-length", str(len(response)))
self.end_headers()
self.wfile.write(response)
except:
Log_Traceback()
# Create ONE socket.
addr = ('', 8000)
sock = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(addr)
sock.listen(5)
# Launch 100 listener threads.
class Thread(threading.Thread):
def __init__(self, i):
threading.Thread.__init__(self)
self.i = i
self.daemon = True
self.start()
def run(self):
httpd = BaseHTTPServer.HTTPServer(addr, Handler, False)
# Prevent the HTTP server from re-binding every handler.
# https://stackoverflow.com/questions/46210672/
httpd.socket = sock
httpd.server_bind = self.server_close = lambda self: None
httpd.serve_forever()
[Thread(i) for i in range(10)]
time.sleep(9e9)
Console log (chrome):
HELLO
hello.html:14 {"req": {"value": "value"}}
hello.html:16
{req: {…}}
req
:
{value: "value"}
__proto__
:
Object
Console log (firefox):
GET
http://XXXXX:8000/hello.html [HTTP/1.0 200 OK 0ms]
POST
XHR
http://XXXXX:8000/postman [HTTP/1.0 200 OK 0ms]
HELLO hello.html:13:3
{"req": {"value": "value"}} hello.html:14:3
Object { req: Object }
Console log (Edge):
HTML1300: Navigation occurred.
hello.html
HTML1527: DOCTYPE expected. Consider adding a valid HTML5 doctype: "<!DOCTYPE html>".
hello.html (1,1)
Current window: XXXXX/hello.html
HELLO
hello.html (13,3)
{"req": {"value": "value"}}
hello.html (14,3)
[object Object]
hello.html (16,3)
{
[functions]: ,
__proto__: { },
req: {
[functions]: ,
__proto__: { },
value: "value"
}
}
Python log:
HTTP 8/postman[post]: PATH='/postman'
URL 8/postman[post]: request data = {"value":"value"}
URL 8/postman[post]: response data = {"req": {"value": "value"}}

- 3,943
- 3
- 28
- 38
You can use XMLHttpRequest, fetch API, ...
If you want to use XMLHttpRequest you can do the following
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({
name: "Deska",
email: "deska@gmail.com",
phone: "342234553"
}));
xhr.onload = function() {
var data = JSON.parse(this.responseText);
console.log(data);
};
Or if you want to use fetch API
fetch(url, {
method:"POST",
body: JSON.stringify({
name: "Deska",
email: "deska@gmail.com",
phone: "342234553"
})
}).then(result => {
// do something with the result
console.log("Completed with result:", result);
}).catch(err => {
// if any error occured, then catch it here
console.error(err);
});

- 1,264
- 11
- 11
There is an easy method to wrap your data and send it to server as if you were sending an HTML form using POST
.
you can do that using FormData
object as following:
data = new FormData()
data.set('Foo',1)
data.set('Bar','boo')
let request = new XMLHttpRequest();
request.open("POST", 'some_url/', true);
request.send(data)
now you can handle the data on the server-side just like the way you deal with reugular HTML Forms.
Additional Info
It is advised that you must not set Content-Type header when sending FormData since the browser will take care of that.

- 477
- 6
- 15
-
1❗️ `FormData` will create a multipart form request rather than an `application/x-www-form-urlencoded` request – ccpizza Feb 07 '20 at 12:35
-
@ccpizza - thank you for clarification. since the OP did not mentioned which type of data is to be POST-ed, I think that FormData is most appropriate way to answer. – Amin Hemati Nik Feb 08 '20 at 09:12
Did you know that JavaScript has it's built-in methods and libs to create forms and submit them?
I am seeing a lot of replies here all asking to use a 3rd party library which I think is an overkill.
I would do the following in pure Javascript:
<script>
function launchMyForm()
{
var myForm = document.createElement("FORM");
myForm.setAttribute("id","TestForm");
document.body.appendChild(myForm);
// this will create a new FORM which is mapped to the Java Object of myForm, with an id of TestForm. Equivalent to: <form id="TestForm"></form>
var myInput = document.createElement("INPUT");
myInput.setAttribute("id","MyInput");
myInput.setAttribute("type","text");
myInput.setAttribute("value","Heider");
document.getElementById("TestForm").appendChild(myInput);
// To submit the form:
myForm.method = "POST";
myForm.action = "whatever.aspx"; // or "response.php"
myForm.submit();
// This will create an INPUT equivalent to: <INPUT id="MyInput" type="text" value="Heider" /> and then assign it to be inside the TestForm tags.
}
</script>
This way (A) you don't need to rely on 3rd parties to do the job. (B) It's all built-in to all browsers, (C) faster, (D) it works, feel free to try it out.
I hope this helps.
H

- 2,476
- 26
- 28
-
I like this reply. Now you've created a form, but how do you send it, though? – étale-cohomology Feb 02 '22 at 21:28
-
Hello, I looked at my reply and you are absolutely right, just revised it and added how to submit, hope all goes well, give me a shout I you need more help, cheers, Heider. – Heider Sati Feb 04 '22 at 13:07
navigator.sendBeacon()
If you simply need to POST
data and do not require a response from the server, the shortest solution would be to use navigator.sendBeacon()
:
const data = JSON.stringify({
example_1: 123,
example_2: 'Hello, world!',
});
navigator.sendBeacon('example.php', data);

- 27,532
- 16
- 147
- 165
-
2Failed to execute 'sendBeacon' on 'Navigator': Beacons are only supported over HTTP(S). – Ali80 May 31 '19 at 21:30
-
1`navigator.sendBeacon` is not meant to be used for this purpose in my opinion. – jolivier Jul 23 '20 at 09:14
The most popular answers here do not show how to get data back from the POST. Also, the popular "fetch" solutions do not work in the latest version of Chrome when sending data to the latest version of NodeJS unless you pass headers and also unwrap the response.json() promise. Also, the popular answers do not use async/await.
Here is the cleanest and most complete solution I could come up with that works.
async function postJsonData(jsonObject) {
const response = await fetch("/echo", {
method: "POST",
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(jsonObject)
});
const actualResponse = await response.json();
}

- 2,280
- 3
- 26
- 37
-
Nice. If somebody wants to use that solution within node.js, read this: https://stackoverflow.com/questions/48433783/referenceerror-fetch-is-not-defined – Gernot Jun 24 '21 at 13:37
const data = { username: 'example' };
fetch('https://example.com/profile', {
method: 'POST', // or 'PUT'
headers: {
' Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then(response => response.json())
.then(data => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});

- 359
- 3
- 6
Here is a nice function you (or anyone else) could use in their code:
function post(url, data) {
return new Promise((res, rej) => {
let stringified = "";
for (const [key, value] of Object.entries(data))
stringified += `${stringified != '' ? '&' : ''}${key}=${value}`
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState == 4)
if (xhr.status == 200)
res(xhr.responseText)
else
rej({ code: xhr.status, text: xhr.responseText })
}
xhr.open("POST", url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(stringified);
})
}

- 61
- 1
- 2
-
-
@Matt, Please clarify what you mean by that. Is that an error that you're getting? – Oscar Knap Dec 29 '21 at 15:30
-
1
-
what does res do? If I wanted to pass the response in json format to a function, there where do I put it in this code? – Nikhil VJ Feb 09 '23 at 18:12
-
if you want the function to return something else, change what is being passed to res – Oscar Knap Feb 20 '23 at 15:53
You can also use this: https://github.com/floscodes/JS/blob/master/Requests.js
You can easily send a http-Request. Just use:
HttpRequest("https://example.com", method="post", data="yourkey=yourdata");
That's it! It should even work if the site is CSRF-protected.
Or just send a GET-Request by using
HttpRequest("https://example.com", method="get");

- 17
- 2
use this func of jbezz library
var makeHttpObject = function () {
try {return new XMLHttpRequest();}
catch (error) {}
try {return new ActiveXObject("Msxml2.XMLHTTP");}
catch (error) {}
try {return new ActiveXObject("Microsoft.XMLHTTP");}
catch (error) {}
throw new Error("Could not create HTTP request object.");
}
function SendData(data){
let type = (data.type ? data.type : "GET")
let DataS = data.data;
let url = data.url;
let func = (data.success ? data.success : function(){})
let funcE =(data.error ? data.error : function(){})
let a_syne = (data.asyne ? data.asyne : false);
let u = null;
try{u = new URLSearchParams(DataS).toString();}catch(e){u = Object.keys(DataS).map(function(k) {return encodeURIComponent(k) + '=' + encodeURIComponent(DataS[k])}).join('&')}
if(type == "GET"){url +="?"+u}
const xhttp = makeHttpObject();
xhttp.onload = function(){func(this.responseText)}
xmlHttp.onreadystatechange = function() {if (xmlHttp.readyState == 4)
{if(xmlHttp.status !== 200){funcE(xmlHttp.statusText)}}}
xhttp.open(type,url,a_syne);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send(u);
}
use this to run :
SendData({
url:"YOUR_URL",
asyne:true,
type:"POST", // or GET
data:{
username:"ali",
password:"mypass" // Your Data
},
success:function(Result){
console.log(Result)
},
error:function(e){
console.log("We Have Some Error")
}
});
Or
download jbezz
and add to your page.
download link : github.com
use :
$$.api({
url:"YOUR_URL",
asyne:true,
type:"POST", // or GET
data:{
username:"ali",
password:"mypass" // Your Data
},
success:function(Result){
console.log(Result)
},
error:function(e){
console.log("We Have Some Error")
}
});

- 47
- 6