I'm learning nodejs, and made a simple site to learn to handle POST requests.
Here is my code:
Browser-side:
function sendRequest (params) {
var xhr = new XMLHttpRequest();
var url = 'result';
xhr.open("POST",url,true);
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.onreadystatechange = function () {
console.log('onreadystatechange');
if(xhr.readyState == 4 && xhr.status == 200){
console.log('Response text:' + xhr.reponseText);
}
}
xhr.send(params);
}
Server-side:
else if (req.url === '/result') {
req.on('data', function (data) {
var params = data.toString().split('&');
var result = calc(params);
console.log(result.toString());
res.writeHead(200,{'Content-Type':'text/plain'});
res.write('<div>'+result.toString()+'</div>');
res.end();
console.log('Response over');
});
}
When i run this,xhr.responseText is undefined, and i'm having trouble understanding where the error is.
Based on the log, node gets the request, the result is correct,and xhr.onreadystatechange also runs(but xhr.responseText is undefined).
There is typing error in your browser side code. You misspelled responseText.
console.log('Response text:' + xhr.responseText);
Related
I'm trying to send a post request to linkedin services from my backend.
exports.GetAccessToken = function (req, res) {
var xhttp = new XMLHttpRequest();
var decoded = jwt.verify(req.query.jwt_token, MariaDB_config.PUB_key);
xhttp.onreadystatechange = function () { // handle request response
if (this.readyState === 4 && this.status === 200) {
console.log("answer : " + this.responseText);
}
};
xhttp.handleError()
// Send a post request
xhttp.open("POST", "https://www.linkedin.com/oauth/v2/accessToken?code=" + decoded.code + "privatestuff", true);
xhttp.send();
}
And I get below error :
TypeError: Cannot read property 'stack' of undefined
This method was working fine until now.
I was using "xhttp.handleError()" wrong, I deleted it and now it works fine.
I'm using slim cropper to upload avatar's on my codeigniter project , It works perfectly on my localhost but on the server , the ajax call to the php that does the image upload keeps giving a 403 forbidden error, below is the section of the code:
function send(url, data, progress, success, err) {
var xhr = new XMLHttpRequest();
if (progress) {
xhr.upload.addEventListener('progress', function (e) {
progress(e.loaded, e.total);
});
}
xhr.open('POST', url, true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var text = xhr.responseText;
// if no data returned from server assume success
if (!text.length) {
success();
return;
}
// catch possible PHP content length problem
if (text.indexOf('Content-Length') !== -1) {
err('file-too-big');
return;
}
// if data returned it should be in suggested JSON format
var obj = null;
try {
obj = JSON.parse(xhr.responseText);
} catch (e) {}
success(obj || text);
} else if (xhr.readyState === 4) {
err('fail');
}
};
xhr.send(data);
}
From what I've read , providing a CSRF token might solve the problem, but the request is made from the same domain and I don't require that on my localhost. What could be the problem?
I'm quite new to node.js and web development in general (so if I'm entirely off base and you have good material for me to consume I'd really like to see it).
I'm trying to prototype passing a JSON object back and forth between node.js server and http client. The client side so far looks like:
<script type="text/javascript">
document.getElementById("myBtn").addEventListener("click", passArg);
function passArg() {
console.log("I'm here")
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST", "/", true);
xmlhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE ) {
if (xmlhttp.status == 200) {
//var json = JSON.parse(xmlhttp.responseText);
}
else if (xmlhttp.status == 400) {
alert('There was an error 400');
}
else {
alert('something else other than 200 was returned');
}
}
}
var data = JSON.stringify({"email":"hey#mail.com","password":"101010"});
xmlhttp.send(data);
get_json();
}
function get_json(){
console.log("getting json");
var xmh = new XMLHttpRequest();
xmh.open("GET", "/playlist/playlist.json", true);
xmh.send();
xmh.onreadystatechange = function() {
if (this.readyState == this.DONE ) {
if (this.status == 200) {
var json = JSON.parse( this.responseText );
console.log(json.email + " "+ json.password + " " + json.access_date);
}
else if (xmh.status == 400) {
alert('There was an error 400');
}
else {
alert('something else other than 200 was returned');
}
}
}
}
</script>
And the server side is coded as
app.post("/", function (req, res) {
console.log('Request received');
req.on('data', function (chunk) {
console.log('GOT DATA!');
json = JSON.parse(chunk);
json.access_date = "12.04.17";
write_json(json)
console.log("finished writing- in app_post")
});
console.log("passing all clear to client")
res.writeHead(200);
res.send();
})
function write_json(chunk){
console.log("WHADDUP")
console.log(JSON.stringify(chunk))
fs = require("fs")
var filename = "./public/playlist/playlist.json";
var file = require(filename);
file = chunk;
fs.writeFile(filename, JSON.stringify(file), function(err){
if (err) return console.log(err);
console.log(JSON.stringify(file));
console.log('writing to ' + fileName);
}
)
console.log("finished writing - in write_json")
}
On the serverside console the following output is generated
Request received
passing all clear to client
GOT DATA!
WHADDUP
{"email":"hey#mail.com","password":"101010","access_date":"12.04.17"}
module.js:428
throw err;
^
SyntaxError: public/playlist/playlist.json: Unexpected end of input
And on the client side of things the console reads
(index):15 I'm here
(index):41 getting json
(index):45 GET http://localhost:8080/playlist/playlist.json net::ERR_CONNECTION_RESET
From this I read that the asynchronous POST event is sending the all clear to call get_json before the file itself is updated. And it seems the updating of the file on the server side isn't working as well. How do I structure the calls to make the edit quite smooth?
The quick answer is to create a function to call res.send, pass it to your write_json function, and invoke it from inside your writeFile callback.
app.post("/", function (req, res) {
console.log('Request received');
req.on('data', function (chunk) {
...
write_json(json, function() {
console.log("passing all clear to client")
res.writeHead(200);
res.send();
console.log("finished writing")
});
});
});
function write_json(chunk, onFinishedWriting){
...
fs.writeFile(filename, JSON.stringify(file), function(err){
if (err) {
return console.log(err);
}
else {
console.log(JSON.stringify(file));
console.log('writing to ' + fileName);
onFinishedWriting();
}
});
}
However when you find yourself writing code like this:
});
});
});
then you are probably in the proverbial "callback hell". I suspect that what you want is to use promises. Here's a question specifically about promises and writeFile that will probably help you.
I need to build a project to get into a JS bootcamp I am applying for. They tell me I may only use vanilla JS, specifically that frameworks and Jquery are not permitted. Up to this point when I wanted to retrieve a JSON file from an api I would say
$.getJSON(url, functionToPassJsonFileTo)
for JSON calls and
$.getJSON(url + "&callback?", functionToPassJsonPFileTo)
for JSONP calls. I just started programming this month so please bear in mind I don't know the difference between JSON or JSONP or how they relate to this thing called ajax. Please explain how I would get what the 2 lines above achieve in Vanilla Javascript. Thank you.
So to clarify,
function jsonp(uri){
return new Promise(function(resolve, reject){
var id = '_' + Math.round(10000 * Math.random())
var callbackName = 'jsonp_callback_' + id
window[callbackName] = function(data){
delete window[callbackName]
var ele = document.getElementById(id)
ele.parentNode.removeChild(ele)
resolve(data)
}
var src = uri + '&callback=' + callbackName
var script = document.createElement('script')
script.src = src
script.id = id
script.addEventListener('error', reject)
(document.getElementsByTagName('head')[0] || document.body || document.documentElement).appendChild(script)
})
}
would be the JSONP equivalent?
Here is the Vanilla JS version for $.getJSON :
var request = new XMLHttpRequest();
request.open('GET', '/my/url', true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
// Success!
var data = JSON.parse(request.responseText);
} else {
// We reached our target server, but it returned an error
}
};
request.onerror = function() {
// There was a connection error of some sort
};
request.send();
Ref: http://youmightnotneedjquery.com/
For JSONP SO already has the answer here
With $.getJSON you can load JSON-encoded data from the server using
a GET HTTP request.
ES6 has Fetch API which provides a global fetch() method that provides an easy, logical way to fetch resources asynchronously across the network.
It is easier than XMLHttpRequest.
fetch(url) // Call the fetch function passing the url of the API as a parameter
.then(res => res.json())
.then(function (res) {
console.log(res)
// Your code for handling the data you get from the API
})
.catch(function() {
// This is where you run code if the server returns any errors
});
Here is a vanilla JS version of Ajax
var $ajax = (function(){
var that = {};
that.send = function(url, options) {
var on_success = options.onSuccess || function(){},
on_error = options.onError || function(){},
on_timeout = options.onTimeout || function(){},
timeout = options.timeout || 10000; // ms
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
//console.log('responseText:' + xmlhttp.responseText);
try {
var data = JSON.parse(xmlhttp.responseText);
} catch(err) {
console.log(err.message + " in " + xmlhttp.responseText);
return;
}
on_success(data);
}else{
if(xmlhttp.readyState == 4){
on_error();
}
}
};
xmlhttp.timeout = timeout;
xmlhttp.ontimeout = function () {
on_timeout();
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
return that;
})();
Example:
$ajax.send("someUrl.com", {
onSuccess: function(data){
console.log("success",data);
},
onError: function(){
console.log("Error");
},
onTimeout: function(){
console.log("Timeout");
},
timeout: 10000
});
I appreciate the vanilla js equivalent of a $.getJSON above
but I come to exactly the same point. I actually was trying of getting rid of jquery which I do not master in any way .
What I'm finally strugglin with in BOTH cases is the async nature of the JSON request.
What I'm trying to achieve is to extract a variable from the async call
function shorten(url){
var request = new XMLHttpRequest();
bitly="http://api.bitly.com/v3/shorten?&apiKey=mykey&login=mylogin&longURL=";
request.open('GET', bitly+url, true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
var data = JSON.parse(request.responseText).data.url;
alert ("1:"+data); //alerts fine from within
// return data is helpless
}
};
request.onerror = function() {
// There was a connection error of some sort
return url;
};
request.send();
}
now that the function is defined & works a treat
shorten("anyvalidURL"); // alerts fine from within "1: [bit.ly url]"
but how do I assign the data value (from async call) to be able to use it in my javascript after the function was called
like e.g
document.write("My tiny is : "+data);
I've got a problem with this Ajax code, is returning 0 everytime I access 'readyState'. Don't know what the source of the problem is yet, any help would be appreciated:
var xhr = null;
function performAjax(inputUrl){
// instantiate XMLHttpRequest object
try{
xhr = new XMLHttpRequest();
alert("XMLHttpRequest");
}
catch(e){
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
// handle old browsers
if( xhr == null ) {
alert("Ajax not supported by your browser");
return;
}
// get the URL
var url = inputUrl;
alert(inputUrl);
// get Ajax answer
xhr.onreadystatechange = handler();
//alert(xhr.readyState);
xhr.open("POST", url, true);
xhr.send(null);
}
function handler() {
alert("Handler: " + xhr.readyState + " Status: " + xhr.status);
// handle only loaded requests
if(xhr.readyState == 4) { // state 4: that data has been received
alert("here");
if(xhr.status == 200) {
alert(xhr.reponseText);
}
else alert("Error with Ajax");
}
}
You're assigning the handler function incorrectly:
xhr.onreadystatechange = handler; // <--- THERE SHOULD BE NO PARENTHESES
When you include the parentheses, you're asking that the function be called. Without them, you're merely referring to the function, which is what you want.