I'm posting successfully to my server , however when requests fails the error object is empty and i cannot construct logic based on the error code
Here is the code and what i see on DEV tools
$http({
method: 'POST',
url: 'my remote api/',
data: {'Account' : $scope.userPhoneNumber, 'Initiator' : initiator.toString()},
headers: {"Authorization": "Basic register:register"}
}).
then(function (response) {
console.log(response.data.AuthenticationUid);
openModalWindow(initiator, response.data.AuthenticationUid);
}, function (data) {
console.log(data);
$scope.phoneNotFound = true;
});
As you can see the printed data object shows status as -1 while it should show 404....
The console output indicates that you are not successfully POSTing to the server. Your OPTIONS request is successful, but your post fails due to missing 'Access-Control-Allow-Origin' headers which is indicative of a CORs error.
Without knowledge of your server it's a bit hard to give you an exact solution, but searching for something along the lines of 'setting up CORS in ' should get you on the right track.
Related
QUESTION:
How to check if a url is valid and actually loads a page ?
With my current code, only the status code is checked, which means that a url like http://fsd.com/ will be considered as valid although it does not load anything.
How can I check that the url actually points to a website that can be loaded ?
CODE:
$.ajax({
url: link,
dataType: 'jsonp',
statusCode: {
200: function() {
console.log( "status code 200 returned");
validURL = true;
},
404: function() {
console.log( "status code 404 returned");
validURL = false;
}
},
error:function(){
console.log("Error");
}
});
EDIT: By valid, I mean that the page is at last partially loaded (as in at least the html & css are loaded) instead of loading forever or somehow failing without the status code being 404.
EDIT2: http://fsd.com actually returns a 404 now as it should...
EDIT3: Another example: https://dsd.com loads an empty page (status code 200) and http://dsd.com actually loads a page with content (status code 200). On my Node.js backend, the npm package "url-exists" indicates that https://dsd.com is invalid, while my frontend with the code shown in my question indicates it is a valid url. This is what the package code looks like: https://github.com/boblauer/url-exists/blob/master/index.js but I wanted to know what would be the best way according to SO users.
EDIT4:
Sadly, the request provided by Addis is apparently blocked by CORS which blocks the execution of the rest of my code while my original request did not.
$.ajax({
type: "HEAD",
url: link,
dataType: 'jsonp',
}).done(function(message,text,response){
const size = response.getResponseHeader('Content-Length');
const status = response.status;
console.log("SIZE: "+size);
console.log("STATUS: "+status);
if(size > 0 && status == "200") {
$("#submitErrorMessage").css("display","none");
$('#directoryForm').submit();
}
else {
$("#submitErrorMessage").css("display","block");
$("#submitLoading").css("display","none");
}
});
EDIT 5:
To be more precise, both requests trigger a warning message in the browser console indicating that the response has been blocked because of CORS but my original code is actually executed in its entirety while the the other request doesn't get to the console.log().
EDIT 6:
$.ajax({
async: true,
url: link,
dataType: 'jsonp',
success: function( data, status, jqxhr ){
console.log( "Response data received: ", data );
console.log("Response data length: ", data.length);
console.log("Response status code: ", status);
if (status == "200" && data.length > 0) {
$("#submitErrorMessage").css("display","none");
$('#directoryForm').submit();
}
else {
$("#submitErrorMessage").css("display","block");
$("#submitLoading").css("display","none");
}
},
error:function(jqXHR, textStatus, errorThrown){
console.log("Error: ", errorThrown);
}
});
Error:
Error: Error: jQuery34108117853955031047_1582059896271 was not called
at Function.error (jquery.js:2)
at e.converters.script json (jquery.js:2)
at jquery.js:2
at l (jquery.js:2)
at HTMLScriptElement.i (jquery.js:2)
at HTMLScriptElement.dispatch (jquery.js:2)
at HTMLScriptElement.v.handle (jquery.js:2)
A successful response without content "should" return a 204: No Content but it doesn't mean that every developer implements the spec correctly. I guess it really depends on what you consider "valid" to mean for your business case.
Valid = 200 && body has some content?
If so you can the test this in the success callback.
$.ajax({
url: link,
dataType: 'jsonp',
success: function (response) {
// todo: test the response for "valid"
// proper length? contains expected content?
},
statusCode: {
200: function() {
console.log( "status code 200 returned");
validURL = true;
},
404: function() {
console.log( "status code 404 returned");
validURL = false;
}
},
error:function(){
console.log("Error");
}
});
I think the word "valid" is used a bit wrongly here. Looking at the code snippet, I can see that you are using HTTP error codes to decide whether the URL is valid or not. However, based on the description, it is clear that you consider the resource (pointed by the URL) to be valid only if it is a web page. I would like to urge the fact that HTTP can be used to access resources which need not have a web page representation.
I think you need to go a bit deeper and retrieve that info (whether it is a web-page representation) from the HTTP response that you receive and just relying on the status code would be misleading for you. One clear indicator would be looking at the response header for content-type: text/html.
Sample response from accessing www.google.com:
date: Tue, 18 Feb 2020 17:51:12 GMT
expires: -1
cache-control: private, max-age=0
content-type: text/html; charset=UTF-8
strict-transport-security: max-age=31536000
content-encoding: br
server: gws
content-length: 58083
x-xss-protection: 0
The HEAD request is used to get meta-information contained in the HTTP headers. The good thing is that the response doesn't contain the body. It's pretty speedy and there shouldn't be any heavy processing going on in the server to handle it. This makes it handy for quick status checking.
The HEAD method is identical to GET except that the server MUST NOT
return a message-body in the response. The metainformation
contained in the HTTP headers in response to a HEAD request SHOULD be
identical to the information sent in response to a GET request. This
method can be used for obtaining metainformation about the entity
implied by the request without transferring the entity-body itself.
This method is often used for testing hypertext links for validity,
accessibility, and recent modification.
www.w3.org
$.ajax({
type: "HEAD",
async: true,
url: link,
dataType: 'json',
}).done(function(message,text,response){
const size = response.getResponseHeader('Content-Length');
//optionally you may check for the status code to know if the request has been successfully completed
const status = response.status;
});
Content-Length is one of the meta-data available in the head request which gives the size of the body in bytes, so by checking the size only without loading the whole page you could check if some content is available in the response body.
-
EDIT:
The above code is for dataType of json. For dataType of jsonp, callback functions for success and error properties will take of the response like the following:
$.ajax({
url: link,
dataType: 'jsonp',
crossDomain: true,
data: data,
success: function( data, status, jqxhr ){
console.log( "Response data received: ", data );
console.log("Response data length: ", data.length);
console.log("Response status code: ", status);
},
error:function(jqXHR, textStatus, errorThrown){
console.log("Error: ", errorThrown);
}
}
What you are trying to accomplish is not very specific, I'm not going to give you a code example on how to do this but here are some pointers.
There are different ways you could get a response: the status code is not tied to the response you get, you could have a 200 response and have no data, or have a 500 error with some data, this could be an html page showing the error or a json object, or even a string specifying what went wrong.
when you say "actually loads a page", I guess you are referring to an html response, you can check for the Content-Type header on your response headers and look for text/html and also check for Content-Length header to check if there is content in your response, and even if you check for those things it's hard to tell if the html actually displays any content.
It really depends on what are you looking specifically, my suggestion is check the Content-Type header and Content-Length and it also depends on the implementation of the website as every one might have different ways of implementing the HTTP protocol.
I am running into CSRF token validation failed error when trying to do a POST request on an endpoint which is on a different server using cors-anywhere. Its mostly because the CSRF Token that I am passing to the cors-server is cached and hence the validation fails.
I have read the following Stack Overflow link - Similar issue
. Turns out my problem is same as the one in the link but since that link does not contain any solution I am asking it here.
Please help.
EDIT:-
$.ajax({
async: false,
crossDomain: true,
data: batch_request,
url: "https://cors-anywhere.herokuapp.com/https://......api.s4hana.ondemand.com:xxx/sap/opu/odata/sap/API_MKT_CONTACT_SRV;v=0002/$batch",
type: "POST",
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Basic xxxxxxxxxxxxxxx");
xhr.setRequestHeader("X-CSRF-Token", "xxxxxxxxx");
xhr.setRequestHeader("Content-Type", "multipart/mixed;boundary=batch");
},
success:function(response) {
console.log("Succesfully added new contacts");
console.log(response);
},
error: function (error) {
console.log("Error");
console.log(error);
}
});
I have made a GET call using POSTMAN and retrieved the CSRF token from the server. For now, I have hardcoded the token in the AJAX call. I receive the following error when I do it-
CSRF validation depends on matching two tokens associated with the request. Typically one is in the request itself and the other is stored in a session associated with the request by a cookie.
Since you are going through a simple proxy, you are anonymising yourself and there is no session associated with the request.
If you want to work around this, then you would need to write your own server-side proxy which maintained the session on a per-user basis.
I'm very new to JSON and JSONP.
I've read through each of the posts that are recommend by the SO search for this error, but I can't seem to get a handle on it.
I have the following code to grab data from an EXTERNAL website:
$.ajax({
url: "https://url.com/authenticate?login=test&apiKey=test",
dataType: 'jsonp',
success:function(json){
console.log("login successful");
}
});
When I load the page, I get:
Uncaught SyntaxError: Unexpected token :
and when I click on the error in Chrome, I see
{"Status":{"Code":"2","Message":"Authentication Succeeded","Success":"true"}}
with a little red x after "true"})
From this, it seems as though I have succeeded in logging in, but I'm doing something else wrong because my console.log("login successful"); never fires. What am I doing wrong?
P.S.
I've tried dataType: 'json' but I get the No 'Access-Control-Allow-Origin' header is present as I'm on a different server, so I went back to jsonP as this is cross-domain.
I've also tried the above url as url: "https://url.com/authenticate?login=test&apiKey=test&callback=?", as I've read I need a callback, but I don't really understand what the functionality of callback is and either way, the error that gets returned (whether &callback=? is in there or not) is:
authenticateUser?login=test&apiKey=test&callback=jQuery111107732549801003188_1423867185396…:1 Uncaught SyntaxError: Unexpected token :
so it's adding the callback in either way....
Also, from the API I'm trying to access:
"this uses the REST protocol, and provides data structured as XML or JSON"
This is not a duplicate of the linked post as the information in the linked post does a great job of explaining what JSONP is, but doesn't answer my specific question regarding why I get data back (so my call is successful,) but why I still get an error and cause my script to stop.
The API you're sending the AJAX request doesn't implement JSONP. It ignores the callback= parameter, and just returns ordinary JSON. But when the browser tries to process this as JSONP, it gets a syntax error because it's not properly formatted. JSONP is a JSON object wrapped in a call to the specified callback function, e.g. it should be sending back:
jQuery111107732549801003188_1423867185396({...});
where {...} is the JSON object you're trying to retrieve. But it's just returning {...}.
You should implement this using a PHP script on your own server. It can be as simple as this:
<?php
$username = urlencode($_POST['user']);
readfile("https://url.com/authenticate?login=$username&apiKey=test");
Then your AJAX call would be:
$.ajax({
url: "yourscript.php",
type: "post",
dataType: "json",
data: { user: "test" },
success: function(json) {
console.log("login successful");
}
});
I have backend webService on tomcat server.always when I perform any request (post, get),code enters on error method.
jQuery code is:
var jqxhr = $.ajax(
{
type:"GET",
url:url
success: function() {
alert("success");
},
error: function() {
alert("fail");
}
});
my url is:
http://"192.168.20.220":6060/NostServices/rest/user/resend_activation_email/mailex#blah.com
error message on log is:
XMLHttpRequest cannot load http://"192.168.20.220":8080/NostServices/rest/user/resend_activation_email/dsgg#sdfkmj.com.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://"192.168.20.220":8383' is therefore not allowed access.
web service server is tomcat.
response of this requset can be 1 for success and -1 for mail not valid
and always enter on fail method and when I try to alert response it output [object object]
thanks you for your help
It's a JSONP request so your server side script needs to return data wrapped in callback:
For example
var url = 'http://example.com/req.json?callback=?';
$.ajax({
type: 'GET',
url: url,
async: false,
jsonpCallback: 'jsonCallback',
contentType: "application/json",
dataType: 'jsonp',
success: function(json) {
console.log(json);
},
error: function(e) {
console.log(e.message);
}
});
And on server side:
jsonCallback({});
As your error says your code is failing because of the cross domain error problem. A very detailed answer is found here:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '...' is therefore not allowed access
Please put in some effort to google these issues, this is a very common thing your trying and all errors have been encountered before and have been resolved somewhere. People will get very annoyed here if you show no effort to debug it yourself or provide all the required detail such as:
All relevant code
Print out of any variables in the code e.g. URL's
Any error message
A list of things you have tried
On a side note a URL should not have quotes it it. It should not be
http://"192.168.1.1":.........
it should be:
http://192.168.1.1:........
I am working with ajax and node js for the first time. When I use the client to get response from node js it gets into the error function. On the other hand, when I directly call the url from the browser, I get the correct response from the server. This is an indication that something is wrong with the client side ajax request.
This is my client code :
function fetch() {
$.ajax({
type: 'POST',
url: "http://127.0.0.1:8888",
data: {data : 'India'},
dataType: 'json',
success: function () {
alert("hi");
//var ret = jQuery.parseJSON(data);
//$('#q').html(ret.msg);
},
error: function (jqXHR, textStatus, error) {
console.log('Error: ' + error.message);
alert("ERROR");
}
});
This is the server node.js code (part of it). The console.log msg get the correct values.
http.createServer(function(req, response) {
console.log("Request received");
response.writeHeader(200, {"Content-Type": "application/json"});
req.on('data', function (chunk) {
console.log(chunk.toString('utf8'));
console.log(result[0].name);
});
response.end(JSON.stringify({data:result}));
}).listen(8888);
All the console.log in the server gets the correct values. That means the response is not reaching back when there is ajax request, but on directly writing 127.0.0.1:8888, I get correct response.
The message on the console is :
XMLHttpRequest cannot load http://127.0.0.1:8888/. Origin null is not allowed by Access-Control-Allow-Origin.
Please someone help to fix this out. I have been on this for a day now.
EDIT : Screen capture of the network tab. As you can see the server gets the request but the client does not get the response. This is done even after writing 'Access-Control-Allow-Origin' : '*'.
This is the Same Origin Policy. You need to supply the HTML document hosting the JavaScript over HTTP (and, unless you are using CORS, from the same hostname and port as the resource you are requesting with Ajax).