I have an XMLHttpRequest that appears fine, it doesn't generate any error I can see but I never see the request sent to the server.
Its like its erroring out, or cancelling, even before the call to the server is made. There is no network request in dev tools networking section.
The biggest thing I notice is that although I am setting xhr.timeout = 15000, the timeout in the xhr object states its 0 - but I don't know if this an issue.
Here is my Request, the only thing printing to console in the response processing is the XHR OTHER console message:
function sendError(url,params) {
return new Promise( function(resolve) {
//url - passed from calling function
//params - JSON.stringify({ var1:var1,var2:var2}) ; - passed from calling script
console.log(url) ; // prints proper url to console
console.log(params) ; // prints proper params to console
var xhr = new XMLHttpRequest();
xhr.responseType = 'json' ;
//var params = JSON.stringify({ type:8,subject:sub.value,message:msg.value,emailAddys:toAddresses }) ;
xhr.onreadystatechange = function() {
var status ;
if (xhr.readyState == 15) {
console.log("XHR Tiemout") ;
console.log("Time out ready state = 15") ;
status = {status:false,errMsg:"Time out ready state = 15"} ;
} else if (xhr.readyState == XMLHttpRequest.DONE) {
console.log("XHR Response") ;
console.log(xhr.response) ;
var res = xhr.response[0] ;
if (xhr.status == 200) {
// process API call results
status = {status:true,errMsg:res.message} ;
} else {
status = {status:false,errMsg:res.message} ;
}
} else {
console.log("XHR OTHER") ; <----- this prints to console everytime
console.log(xhr) ;
status = {status:false,errMsg:"Something went wrong, no response from server"} ;
}
resolve(status) ;
}
xhr.open('POST', url, true);
xhr.setRequestHeader('Pragma' , 'no-cache') ;
xhr.setRequestHeader('Expires' , -1) ;
xhr.setRequestHeader('Cache-Control' , 'no-cache,no-store,must-revalidate') ;
xhr.setRequestHeader('Content-Type' , 'application/json') ;
xhr.setRequestHeader('X-Requested-With' , 'com.mydomain') ;
xhr.setRequestHeader('Authorization' , 'Token ' +clientToken) ;
xhr.timeout = 15000 ; // 15 seconds
xhr.ontimeout = function() { console.log("Timed Out!") ; };
xhr.send(params);
}) ;
}
And here is the xhr i am printing to console, there is a sendError in the onreadystatechange() function, but I don't understand the root of the error:
Related
I'm using a Cloudflare worker to return a JSON. The code running on the worker is pretty simple
//return JSON
const data = {
pswd: psk_db,
};
json = JSON.stringify(data, null, 2);
}
return new Response(json, {
headers: {
'content-type': 'application/json;charset=UTF-8',
"Access-Control-Allow-Origin": "*",
},
})
Now, for some reason, I correctly recieve the response but when I call the javascript
var parsed = JSON.parse(Http.response);
document.getElementById("json_response_code").textContent = parsed.pswd;
I got
Uncaught SyntaxError: Unexpected end of JSON input
at JSON.parse (<anonymous>)
at RequestCode.Http.onreadystatechange (index.html:83:27)
But I still correctly get the value on parsed.pswd
I can't find the issue as the code works but it throws error anyway
EDIT
Console.log(Http.response) shows
{
"pswd": "nicola"
}
Yes, I'm using it; added code
const Http = new XMLHttpRequest();
const url = my_url;
Http.open("GET", url);
Http.send();
Http.onreadystatechange = (e) => {
console.log(Http.response);
var parsed = JSON.parse(Http.response);
document.getElementById("json_response_code").textContent = parsed.pswd;
};
As suggested by #Jaromanda-X Http.onreadystatechange = (e) was used in the wrong way.
Solution has been
Http.onload = (e) => {
// In local files, status is 0 upon success in Mozilla Firefox
if (Http.readyState === XMLHttpRequest.DONE) {
const status = Http.status;
if (status === 0 || (status >= 200 && status < 400)) {
// The request has been completed successfully
console.log(Http.responseText);
var parsed = JSON.parse(Http.response);
document.getElementById("json_response_code").textContent =
parsed.pswd;
} else {
// Oh no! There has been an error with the request!
console.log(Error);
}
}
};
Http.send();
I'm sending HTTP requests and receiving responses with the following code:
var xhr = new XMLHttpRequest()
var waiting = true
var sup = this
var userId = userInfo.userId
var userType = 'student'
if (userInfo.type == 2) {
userType = 'professor'
}
xhr.onreadystatechange = function() {
try {
if (this.status == 200 && waiting) {
waiting = false;
var courses
try {
courses = JSON.parse(xhr.response)
} catch (jerr) {
courses = []
}
sup.courseArray = courses;
console.log(sup.courseArray)
sup.render()
}
} catch (err) {}
}
xhr.open('GET', 'http://localhost:8080/course/read/' + userType + 'Id/' + userId)
xhr.send()
As you can see, I'm only accessing response in the callback, so the server has responded and xhr has been initialized at that point. If I simply call console.log(xhr), I can clearly see response is a non-empty string:
response: "[{\"id\":1,\"professorId\":1,\"name\":\"java\",\"code\":\"CS1017\"}]"
However, if I call console.log(xhr.response), I get
<empty string>
Does anyone know why I'm seeing this discrepancy?
this.status == 200 will be true as soon as xhr.readyState == 2, but the request will not be completely fulfilled until xhr.readyState == 4; at readyState == 2 response will still be empty.
console.log(xhr) will eventually show the status at readyState == 4, but that's 2 readyStates later than when your code tries to access xhr.response.
You have to check that both status == 200 and readyState == 4 are true to be sure a complete response has arrived.
why not try using using JS native fetch instead
var waiting = true
var sup = this
var userId = userInfo.userId
var userType = 'student'
if(userInfo.type == 2) {
userType = 'professor'
}
fetch('http://localhost:8080/course/read/' + userType + 'Id/' + userId)
.then(r => r.json())
.then((response) => {
waiting = false;
sup.courseArray = response;
console.log(sup.courseArray);
sup.render();
})
.catch((e) => {
waiting = false;
console.log(e);
});
I have a strange behaviour when I am trying to upload data to Spring MVC and download a file using Spring MVC.
This is the server side:
#RequestMapping(method = RequestMethod.POST, value = "/generate", consumes = {"multipart/form-data"}, produces = {"multipart/form-data"})
public ResponseEntity generate(#RequestParam final MultipartFile myMultipartFile)
{
ResponseEntity responseEntity = null ;
try
{
responseEntity = this.generateInternal(myMultipartFile) ;
}
catch (IOException ioException)
{
responseEntity = ResponseEntity.status(HttpStatus.FORBIDDEN).body(ioException.getMessage()) ;
}
return responseEntity ;
}
(1) On the other hand, the following code is working properly:
var input = document.getElementById('myFile');
var xhr = new XMLHttpRequest() ;
var formData = new FormData();
formData.append("myMultipartFile", input.files[0]) ;
xhr.open('POST', "http://localhost:8080/generate", true) ;
xhr.responseType = "blob" ;
xhr.withCredentials = false ;
xhr.onreadystatechange = function ()
{
if (xhr.readyState == 4 && xhr.status == 200)
{
var blob = xhr.response;
console.log("This code is working properly, I can download the file") ;
}
};
xhr.send(formData) ;
(2) But...the following code is not working properly :(
var xhr = new XMLHttpRequest() ;
var formData = new FormData();
formData.append("myMultipartFile", "The content is a YAML") ;
xhr.open('POST', "http://localhost:8080/generate", true) ;
xhr.responseType = "blob" ;
xhr.withCredentials = false ;
xhr.onreadystatechange = function ()
{
if (xhr.readyState == 4 && xhr.status == 200)
{
var blob = xhr.response;
console.log("This code is never executed, I got a 402 HTTP Error") ;
}
};
xhr.send(formData) ;
In this second example (2), I got an error in the browser (406 (Not Acceptable)). If I add the dependency 'spring-boot-starter-actuator' in the Java project (to monitorize the requests - using "/trace"), I got the following response info:
response: {
X-Application-Context: "application",
status: "400"
}
The previous response is quite different than the correct response (1):
response: {
X-Application-Context: "application",
Content-Type: "multipart/form-data;charset=UTF-8",
Transfer-Encoding: "chunked",
Date: "Mon, 20 Jun 2016 15:43:52 GMT",
status: "200"
}
The only difference between the (1) and (2) is the mechanism to send the file:
(1) Sends via "File"
(2) Sends via "String"
Has anyone had this strange behaviour? How did you resolve it?
Many thanks.
Regards,
Paco.
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.
I have this code to make an ajax request, but according to Chrome Inspector the callback associated with the request is being called twice (by this I mean the response is being logged into the console twice), 2 more logs are being printed without any content. Here's the code:
var ajax = {
pull: function (settings) {
settings.type = 'get';
settings.callback = typeof (settings.callback) === 'function' ? settings.callback : false;
settings.data = settings.data ? settings.data : null;
return this.request(settings.url, settings.type, settings.callback, settings.data);
},
request: function (url, type, callback, data) {
var ids = ['MSXML2.XMLHTTP.3.0',
'MSXML2.XMLHTTP',
'Microsoft.XMLHTTP'],
xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
for (var i = 0; i < ids.length; i++) {
try {
xhr = new ActiveXObject(ids[i]);
break;
} catch (e) {}
}
}
if (callback) {
xhr.onreadystatechange = function () {
callback(xhr);
};
}
xhr.open(type, url, true);
if (type.toUpperCase() === 'GET') {
xhr.send();
} else if (type.toUpperCase() === 'POST') {
xhr.send(data);
}
}
}
ajax.pull({
url: 'http://localhost/my/twtools/scripts/ajax.php',
callback: function (xhr) {
console.log(xhr.response);
}
});
xhr.onreadystatechange has several steps (numbered from 0 top 4 I do believe something like 0 = uninitialized, 1 = starting etc, although I can't rember the exact names of the steps anymore, a quick google should find them), and each step is calling your callback. If I remember correctly, the last stage is 4, so I do believe you need to check something like this
if (xhr.readyState == 4 && xhr.status == 200)
{
// call has finished successfully
}
inside you callback, i.e. to check that it is all finished and got a successful response
I've been spoilt by jQuery these days (so much easier to do with jQuery), been quite a while since I wrote raw ajax
You're using onreadystatechange, which gets called more than once (once each state change).
Try using
xhr.onload = function() {
callback(xhr);
};