AJAX POST request with response - javascript

As the title states, I'm looking to make a POST request using JavaScript and also get a response. Here's my current code:
var request = new XMLHttpRequest();
request.open('POST', 'test.php', true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
// Success
console.log(request.responseText)
} else {
// Server-side Error
console.log("Server-side Error")
}
};
request.onerror = function() {
// Connection Error
console.log("Connection Error")
};
request.send({
'color':'red',
'food': 'carrot',
'animal': 'crow'
});
With test.php being:
<?php
echo $_POST['color'];
?>
This should return 'red' but instead returns nothing.
This seems like a simple problem but I could only find solutions for people using jQuery. I'd like a solution that does not rely on and libraries.

The send method takes a string rather than an object, perhaps more like:
var request = new XMLHttpRequest();
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
console.log(request.response)
} else {
console.log("Server-side Error")
}
};
request.onerror = function() {
console.log("Connection Error")
};
request.open('POST', 'test.php', true);
request.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
request.send('color=red&food=carrot&animal=crow');

The JavaScript problem
You are trying to send a generic Object, so it gets converted to a String ("[Object object]"), and the data is lost.
Convert the data to a FormData object instead.
var data = {
'color':'red',
'food': 'carrot',
'animal': 'crow'
};
var formData = new FormData();
Object.keys(data).forEach(function (key) {
formData.append(key, data[key]);
})
request.send(formData);
The PHP problem
All of the current solutions simply log the source code of "test.php" to the console as opposed to logging 'red' to the console
This is an issue unrelated to your code. It is also a FAQ. See: PHP code is not being executed, instead code shows on the page

Related

I can't get a response from the server

I followed some guides on how to send json objects to the server(written using node.js) and it doesn't work, I have no idea what is wrong. I know that my server works fine since I tested it on postman so it's my js code that's the problem, all the tutorials I see follow a similar XMLHttpRequest format.
this is my code
var ing = new Ingredient(name, date, qty, rp);
var url = "http://localhost:8081/addIngredient";
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
//Send the proper header information along with the request
// application/json is sending json format data
xhr.setRequestHeader("Content-type", "application/json");
// Create a state change callback
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
// Print received data from server
result.innerHTML = this.responseText;
}
};
// Converting JSON data to string
var data = JSON.stringify(ing);
document.write(data);
// Sending data with the request
xhr.send(data);
I used document.write to check where the code stops working but everything passes (since the document.write prints something), I suspect that there is something wrong/missing from xhr.send(data) but I can't tell what. Finally, nothing gets printed from the callback.
It's better to use onload instead of onreadystatechange
xhr.onload = function() {
if (xhr.status == 200) {
console.log(`Response length = ${xhr.response.length}`);
// store xhr.response here somewhere
}
};

Symfony 3 - Sending AJAX request as XmlHttpRequest() (javascript) does not pick up request as XmlHttpRequest in backend

I have an ExceptionListener implemented in Symfony3 (also works in Symfony2). The ExceptionListener identifies whether the request was normal HTTP or AJAX (XmlHttpRequest) and generates a response accordingly. When using jQuery .post() or .ajax(), the ExceptionListener returns $request->isXmlHttpRequest() as TRUE, but when using javascript var xhr = new XmlHTTPRequest(), the ExceptionListener returns $request->isXmlHttpRequest() as FALSE. I am using the latter in a small amount of instances where files need to be uploaded via AJAX (which cannot be done using .post() or .ajax().
I am looking for a solution (either frontend or backend) to resolve my ExceptionListener incorrectly picking this up as a normal HTTP request.
Frontend Code:
function saveUser()
{
var form = document.getElementById('userForm');
var formData = new FormData(form);
var xhr = new XMLHttpRequest();
xhr.open('POST', '{{url('saveUser')}}', true);
xhr.onreadystatechange = function (node)
{
if (xhr.readyState === 4)
{
if (xhr.status === 200)
{
var data = JSON.parse(xhr.responseText);
if (typeof(data.error) != 'undefined')
{
$('#processing').modal('hide');
$('#errorMsg').html(data.error);
$('#pageError').modal('show');
}
else
{
$('#successMsg').html('User Successfully Saved');
$('#processing').modal('hide');
$('#pageSuccess').modal('show');
$('#userModal').modal('hide');
updateTable();
}
}
else
{
console.log("Error", xhr.statusText);
}
}
};
$('#processing').modal('show');
xhr.send(formData);
return false;
}
ExceptionListener.php (partial)
# If AJAX request, do not show error page.
if ($request->isXmlHttpRequest()) # THIS RETURNS FALSE ON JS XmlHTTPRequest()
{
$response = new Response(json_encode(array('error' => 'An internal server error has occured. Our development team has been notified and will investigate this issue as a matter of priority.')));
}
else
{
$response = new Response($templating->render('Exceptions/error500.html.twig', array()));
}
When using vanilla ajax you need to pass the following header to your ajax request
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

Junk after document element. How to avoid XML parsing with ajax get (XMLHttpRequest) in vanilla javascript?

Firefox & AJAX Junk after document element
I'm having pretty much the exact same problem as the above question, but for different reasons.
To reiterate the problem:
I have some html file:
<style> #hat { color: red; } </style>
<script> var hat = "fez"; </script>
Which I'm retreiving via vanilla ajax call:
var request = new XMLHttpRequest();
request.open('GET', target, true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
// Success!
var response = 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();
That is throwing an error in console:
junk after document element
I don't want the html file parsed at all. I've tried searching for a non XML HttpRequest method, but JQuery is all I can find on the subject. Perhaps there is something like a TextHttpRequest that just retrieves text without parsing it? Or maybe there's a way to tell an XMLHttpRequest that parsing is unnecessary?
This all seems like it should be pretty obvious, but I just keep finding tutorials on ajax that use jquery.
Here's a link to the MDN
All you should need to do is add this line before .send():
request.responseType = 'text';
This worked for me:
var request = new XMLHttpRequest();
// add a responseType here
request.responseType = 'text';
request.open('GET', target, true);
request.onload = function() {
if (request.status == 200) {
// Success!
var response = request.responseText;
document.body.innerText = response;
} else {
// We reached our target server, but it returned an error
alert('there was an error in the response.\n\n Error: ' + request.status);
}
};
request.onerror = function() {
// There was a connection error of some sort
alert('there was an error in the request');
};
request.send();

What is the vanilla JS version of Jquery's $.getJSON

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

how to find out if XMLHttpRequest.send() worked

I am using XMLHttpRequest to send a file from javascript code to a django view.I need to detect,whether the file has been sent or if some error occurred.I used jquery to write the following javascript.
Ideally I would like to show the user an error message that the file was not uploaded.Is there some way to do this in javascript?
I tried to do this by returning a success/failure message from django view , putting the success/failed message as json and sending back the serialized json from the django view.For this,I made the xhr.open() non-asynchronous. I tried to print the xmlhttpRequest object's responseText .The console.log(xhr.responseText) shows
response= {"message": "success"}
What I am wondering is,whether this is the proper way to do this.In many articles,I found the warning that
Using async=false is not recommended
So,is there any way to find out whether the file has been sent,while keeping xhr.open() asynchronous?
$(document).ready(function(){
$(document).on('change', '#fselect', function(e){
e.preventDefault();
sendFile();
});
});
function sendFile(){
var form = $('#fileform').get(0);
var formData = new FormData(form);
var file = $('#fselect').get(0).files[0];
var xhr = new XMLHttpRequest();
formData.append('myfile', file);
xhr.open('POST', 'uploadfile/', false);
xhr.send(formData);
console.log('response=',xhr.responseText);
}
My django view extracts file from form data and writes to a destination folder.
def store_uploaded_file(request):
message='failed'
to_return = {}
if (request.method == 'POST'):
if request.FILES.has_key('myfile'):
file = request.FILES['myfile']
with open('/uploadpath/%s' % file.name, 'wb+') as dest:
for chunk in file.chunks():
dest.write(chunk)
message="success"
to_return['message']= message
serialized = simplejson.dumps(to_return)
if store_message == "success":
return HttpResponse(serialized, mimetype="application/json")
else:
return HttpResponseServerError(serialized, mimetype="application/json")
EDIT:
I got this working with the help of #FabrícioMatté
xhr.onreadystatechange=function(){
if (xhr.readyState==4 && xhr.status==200){
console.log('xhr.readyState=',xhr.readyState);
console.log('xhr.status=',xhr.status);
console.log('response=',xhr.responseText);
var data = $.parseJSON(xhr.responseText);
var uploadResult = data['message']
console.log('uploadResult=',uploadResult);
if (uploadResult=='failure'){
console.log('failed to upload file');
displayError('failed to upload');
}else if (uploadResult=='success'){
console.log('successfully uploaded file');
}
}
}
Something like the following code should do the job:
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState === 4) {
var response = JSON.parse(xmlhttp.responseText);
if (xmlhttp.status === 200) {
console.log('successful');
} else {
console.log('failed');
}
}
}
XMLHttpRequest objects contain the status and readyState properties, which you can test in the xhr.onreadystatechange event to check if your request was successful.
XMLHttpRequest provides the ability to listen to various events that can occur while the request is being processed. This includes periodic progress notifications, error notifications, and so forth.
So:
function sendFile() {
var form = $('#fileform').get(0);
var formData = new FormData(form);
var file = $('#fselect').get(0).files[0]
var xhr = new XMLHttpRequest();
formData.append('myfile', file);
xhr.open('POST', 'uploadfile/', false);
xhr.addEventListener("load", transferComplete);
xhr.addEventListener("error", transferFailed);
}
function transferComplete(evt) {
console.log("The transfer is complete.");
// Do something
}
function transferFailed(evt) {
console.log("An error occurred while transferring the file.");
// Do something
}
You can read more about Using XMLHttpRequest.

Categories

Resources