Pure JavaScript Send POST Data Without a Form

600,128

Solution 1

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();

Solution 2

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"});

Solution 3

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.

Solution 4

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"}}

Solution 5

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: "[email protected]",
    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: "[email protected]",
        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);
    });
Share:
600,128

Related videos on Youtube

John
Author by

John

Updated on February 05, 2022

Comments

  • John
    John about 2 years

    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)?

  • FluorescentGreen5
    FluorescentGreen5 almost 7 years
    could you write an example for someStuff?
  • Camel
    Camel almost 7 years
    someStuff = 'param1=val1&param2=val2&param3=val3'
  • JamesC
    JamesC over 6 years
    That'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: (requestb.in)
  • Hylle
    Hylle over 5 years
    What is the true boolean variable in xhr.open for?
  • BlackICE
    BlackICE over 5 years
  • Ali80
    Ali80 almost 5 years
    Failed to execute 'sendBeacon' on 'Navigator': Beacons are only supported over HTTP(S).
  • jbg
    jbg over 4 years
    the application/x-www-form-urlencoded MIME type doesn't have a charset parameter: iana.org/assignments/media-types/application/…
  • ccpizza
    ccpizza about 4 years
    ❗️ FormData will create a multipart form request rather than an application/x-www-form-urlencoded request
  • Amin Hemati Nik
    Amin Hemati Nik about 4 years
    @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.
  • jolivier
    jolivier almost 4 years
    navigator.sendBeacon is not meant to be used for this purpose in my opinion.
  • Spacehold
    Spacehold about 3 years
    "Invalid Name Error"
  • OCDev
    OCDev almost 3 years
    Because 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.
  • Gernot
    Gernot almost 3 years
    Nice. If somebody wants to use that solution within node.js, read this: stackoverflow.com/questions/48433783/…
  • Hannes Schneidermayer
    Hannes Schneidermayer almost 3 years
    fetch API is the current way to go
  • Michael Artman
    Michael Artman over 2 years
    This is the old way of doing requests. I highly recommend not using this method and use fetch function instead.
  • Matt
    Matt over 2 years
    res and rej are not defined.
  • Frijey Labs
    Frijey Labs over 2 years
    Thanks, worked as a charm.
  • Khaled Developer
    Khaled Developer over 2 years
    @José i do my best.
  • Oscar Knap
    Oscar Knap over 2 years
    @Matt, Please clarify what you mean by that. Is that an error that you're getting?
  • Oscar Knap
    Oscar Knap over 2 years
    res and rej are defined on line 2.
  • étale-cohomology
    étale-cohomology about 2 years
    I like this reply. Now you've created a form, but how do you send it, though?
  • Heider Sati
    Heider Sati about 2 years
    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.
  • Rhys Broughton
    Rhys Broughton about 2 years
    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'
  • Nico Bako
    Nico Bako about 2 years
    Direct link to fetch function parameters documentation developer.mozilla.org/en-US/docs/Web/API/fetch#parameters