128

I need to send a JSON (which I can stringify) to the server and to retrieve the resulting JSON on the user side, without using JQuery.

If I should use a GET, how do I pass the JSON as a parameter? Is there a risk it would be too long?

If I should use a POST, how do I set the equivalent of an onload function in GET?

Or should I use a different method?

REMARK

This question is not about sending a simple AJAX. It should not be closed as duplicate.

Damjan Pavlica
  • 21,431
  • 6
  • 55
  • 65
Jérôme Verstrynge
  • 51,859
  • 84
  • 263
  • 429
  • You need to use `XMLHttpRequest`. The name notwithstanding, you can use it for JSON data (and that is actually how jQuery does it in the background). – elixenide Jun 28 '14 at 15:48
  • Ok, but how do I feed the JSON when sending the XMLHttpRequest – Jérôme Verstrynge Jun 28 '14 at 15:50
  • 2
    I would POST the data. Have a look at this: http://youmightnotneedjquery.com. It shows how you can get/post data with vanilla JS. – HaukurHaf Jun 28 '14 at 15:59
  • For GET you could use : var params = "somevariable=somevalue&anothervariable=anothervalue"; var http = new XMLHttpRequest(); http.open("GET", url+"?"+params, true); http.onreadystatechange = function() { if(http.readyState == 4 && http.status == 200) { alert(http.responseText); } } http.send(null); However using post is better if you do not want the params to be visible you could use x.send('name1='+string+'&name2=value2'); in the above – ebiv Jun 28 '14 at 16:01
  • 1
    @Ed Cottrell The referenced question has nothing to do with this one. The reference is taking about (JUST) `sending` an ajax request, which is a quite general thing. This one is asking for `sending` but and `receiving JSON` in pure JavaScript. Furthermore, in order to send this JSON back, you have to know how to solve this part of the problem on the `server-side` which is another thing not mentioned on referenced question. – hex494D49 Jul 01 '14 at 12:32
  • @hex494D49 The prior question is spot-on; it shows how to receive the response using `.onreadystatechange` and `.responseText`. To process the response, you just need to process `.responseText`. Regarding sending information via `POST` (whether it's JSON data or something else), you might also see [this question](http://stackoverflow.com/questions/9713058/sending-post-data-with-a-xmlhttprequest). – elixenide Jul 01 '14 at 14:13
  • 1
    @Ed Cottrell The question you referred to does not have an approved answer and uses old methods to create the Ajax request. It does not provide a full answer to this question. My question is more subtle than a traditional Ajax POST or GET. You missed the point. – Jérôme Verstrynge Jul 01 '14 at 14:24
  • @JVerstry If I'm missing something, I'd be happy to nominate this for reopening. As I understand it, you have asked how to send JSON from a browser to a server and retrieve the (JSON) response. You have particularly asked about how to set the equivalent of an onload function. The answers to these questions are thoroughly covered in the questions to which I have linked. What am I missing? – elixenide Jul 01 '14 at 14:28
  • @Ed Cottrell First, XMLHttpRequest does not have an onload function, but onreadystatechange. Moreover, browsers are not capable of parsing JSON as responses to POST requests by default. Hence, hex494D49 answers the specific and subtle point raised in this question (which you are missing). Second, a duplicate question means the same question has been asked already. You are referring to two questions which are different than the question being asked and claim this question is a duplicate of your questions, when they don't even answer this question in the first place. That's not how SO works... – Jérôme Verstrynge Jul 01 '14 at 14:47
  • 1
    @JVerstry `onreadystatechange` is what you use to emulate `onload`, as shown by the accepted answer below. For parsing, you just use `JSON.parse()` (again, as shown in the answer), but I was assuming that you already knew that since you mentioned stringifying in the question. I have tried to help you by pointing you to not 1 but 2 questions covering these points. There's obviously some difference -- rarely are 2 questions *exactly* identical -- but it's trivial if you already know how to stringify and parse JSON. That said, since you and @hex494D49 disagree, I am nominating this for reopening. – elixenide Jul 01 '14 at 15:00

2 Answers2

240

Sending and receiving data in JSON format using POST method

// Sending and receiving data in JSON format using POST method
//
var xhr = new XMLHttpRequest();
var url = "url";
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
    if (xhr.readyState === 4 && xhr.status === 200) {
        var json = JSON.parse(xhr.responseText);
        console.log(json.email + ", " + json.password);
    }
};
var data = JSON.stringify({"email": "hey@mail.com", "password": "101010"});
xhr.send(data);

Sending and receiving data in JSON format using GET method

// Sending a receiving data in JSON format using GET method
//      
var xhr = new XMLHttpRequest();
var url = "url?data=" + encodeURIComponent(JSON.stringify({"email": "hey@mail.com", "password": "101010"}));
xhr.open("GET", url, true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
    if (xhr.readyState === 4 && xhr.status === 200) {
        var json = JSON.parse(xhr.responseText);
        console.log(json.email + ", " + json.password);
    }
};
xhr.send();

Handling data in JSON format on the server-side using PHP

<?php
// Handling data in JSON format on the server-side using PHP
//
header("Content-Type: application/json");
// build a PHP variable from JSON sent using POST method
$v = json_decode(stripslashes(file_get_contents("php://input")));
// build a PHP variable from JSON sent using GET method
$v = json_decode(stripslashes($_GET["data"]));
// encode the PHP variable to JSON and send it back on client-side
echo json_encode($v);
?>

The limit of the length of an HTTP Get request is dependent on both the server and the client (browser) used, from 2kB - 8kB. The server should return 414 (Request-URI Too Long) status if an URI is longer than the server can handle.

Note Someone said that I could use state names instead of state values; in other words I could use xhr.readyState === xhr.DONE instead of xhr.readyState === 4 The problem is that Internet Explorer uses different state names so it's better to use state values.

Hasan A Yousef
  • 15,770
  • 15
  • 88
  • 140
hex494D49
  • 8,125
  • 3
  • 34
  • 44
  • 4
    Should be `xhr.status === 200` . – qed May 11 '17 at 14:37
  • I'm using the same code to post the JSON data to the REST API that is hosted o the localhost but getting the error `XHR failed loading: POST` – viveksinghggits Jul 06 '17 at 17:34
  • @viveksinghggits First, check if the code from above works on your localhost. If it does (and it should work) then the problem must be somewhere on your server side; if it doesn't, let me know and I'll check it. This way, having nothing of your code, I can't help you. – hex494D49 Jul 06 '17 at 20:12
  • @hex494D49 so thankful for you response, i was actually firing the XHR on the submit action of the form, when I changed it to be fired by a click event on. I got the CORS error, that is understandable and I am changing my server side code for that. I wrote about it here https://medium.com/@viveksinghggits/avoid-firing-xhrs-on-a-forms-submit-action-76ab37515834 – viveksinghggits Jul 06 '17 at 21:04
12

Using new api fetch:

const dataToSend = JSON.stringify({"email": "hey@mail.com", "password": "101010"});
let dataReceived = ""; 
fetch("", {
    credentials: "same-origin",
    mode: "same-origin",
    method: "post",
    headers: { "Content-Type": "application/json" },
    body: dataToSend
})
    .then(resp => {
        if (resp.status === 200) {
            return resp.json()
        } else {
            console.log("Status: " + resp.status)
            return Promise.reject("server")
        }
    })
    .then(dataJson => {
        dataReceived = JSON.parse(dataJson)
    })
    .catch(err => {
        if (err === "server") return
        console.log(err)
    })

console.log(`Received: ${dataReceived}`)                
You need to handle when server sends other status rather than 200(ok), you should reject that result because if you were to left it in blank, it will try to parse the json but there isn't, so it will throw an error
AJP
  • 21,889
  • 17
  • 76
  • 108
John Balvin Arias
  • 1,665
  • 2
  • 17
  • 25