catch jquery ajax error later - javascript

I try to make an http request to a freebox ( I don't know if it's exist outside france )
The freebox don't access the CORS request, but she make what I will.
For example if I make a request for power :
http://hd1.freebox.fr/pub/remote_control?code=5818260&key=power&long=false&repeat=1
The freebox player start, and I have a CORS error:
XMLHttpRequest cannot load http://hd1.freebox.fr/pub/remote_control?code=5818260&key=power&long=false&repeat=1. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
It's okay, but I will check the http header for this request, for example if I will check if my code is good, the freebox return 403 for bad code.
I tried to get the statusCode with Jquery :
xhr = $.ajax({
method: "GET",
url: url,
crossDomain: true,
statusCode: {
500: function () {
alert("Une erreur s'est produite !");
},
403: function(){
alert("aaaaa")
throw new badTelecommandeCode();
},
404: function(){
throw new freeboxNotFound();
},
0: function(){console.log(0)}
},
error: function (err) {
console.log(err);
}
});
All this time, the status code is 0, and "error" don't launch. I have this error in console :
XMLHttpRequest cannot load http://hd1.freebox.fr/pub/remote_control?code=5818260&key=power&long=false&repeat=1. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 403.
You can see the end of this answer
"The response had HTTP status code 403.".
Just before jquery write an error ( in red ):
GET http://hd1.freebox.fr/pub/remote_control?code=5818260&key=power&long=false&repeat=1
I try to catch the error :
try{
xhr = $.ajax({
method: "GET",
url: url,
crossDomain: true,
statusCode: {
500: function () {
alert("Une erreur s'est produite !");
},
403: function(){
alert("aaaaa")
throw new badTelecommandeCode();
},
404: function(){
throw new freeboxNotFound();
}
},
error: function (err) {
console.log(err);
}
});
}
catch(err){
console.log(err);
}
I have try to search, where the error has catch by jquery :
http://code.jquery.com/jquery-2.1.4.js line 8634
Do You find a way for catch the CORS message, and parse it, or catch the jquery message, and why not get the statusCode or any information .
For the little troller, the way "Send a request to freebox developer for accept CORS" is already make, but no answer. I can't pass by a webserver .
My Current challenge is : "I'm a lambda user will see my TV, but my Free Tv Remote don't work, what I can make easily, with my smartphone/PC"
UPDATE1 :
I have make an example :
if it's work good :
xhr = $.ajax({
method: "GET",
url: "http://hd1.freebox.fr/pub/remote_control?code=5818261&key=right&long=false&repeat=1",
crossDomain: true,
statusCode: {
500: function () {
alert("Une erreur s'est produite !");
},
403: function(){
alert("badTelecommandeCode")
},
404: function(){
alert("freeboxNotFound")
}
},
error: function (err) {
// console.log(err);
},
fail:function(jqxhr, textStatus, errorThrown) {
// console.log(errorThrown);
}
});
Good key, good code, my TV make the action, and return a CORS error
I will catch, if the code is bad, or if the key doesn't exist :
xhr = $.ajax({
method: "GET",
url: "http://hd1.freebox.fr/pub/remote_control?code=5818261&key=ping",
crossDomain: true,
statusCode: {
500: function () {
alert("Une erreur s'est produite !");
},
403: function(){
alert("badTelecommandeCode")
},
404: function(){
alert("freeboxNotFound")
}
},
error: function (err) {
// console.log(err);
},
fail:function(jqxhr, textStatus, errorThrown) {
// console.log(errorThrown);
}
});
xhr = $.ajax({
method: "GET",
url: "http://hd1.freebox.fr/pub/remote_control?code=222222&key=ping",
crossDomain: true,
statusCode: {
500: function () {
alert("Une erreur s'est produite !");
},
403: function(){
alert("badTelecommandeCode")
},
404: function(){
alert("freeboxNotFound")
}
},
error: function (err) {
// console.log(err);
},
fail:function(jqxhr, textStatus, errorThrown) {
// console.log(errorThrown);
}
});
I have a CORS, no problem, but how I can catch the text, say the http status .
For information :
freebox.fr is a NAT rules, redirect to my router ( the freebox ), hdX.freebox.fr go to the API for TV player hd number X

Still not certain interpret Question correctly. There does not appear to be a response returned from url . 0 does not appear to be a valid HTTP response code see HTTP status code 0 - what does this mean for fetch, or XMLHttpRequest? . The error logged to console
GET http://hd1.freebox.fr/pub/remote_control?code=5818260&key=power&long=false&repeat=1 net::ERR_CONNECTION_TIMED_OUT
after request below
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://hd1.freebox.fr/pub/remote_control?code=5818260&key=power&long=false&repeat=1", true);
xhr.onload = function() {
console.log(this.status)
}
xhr.onerror = function(e) {
console.log(e, this.status)
}
xhr.send();

Related

Cors Policy Error when sending Authentication Bearer token - node.js (Google cloud functions)

I am trying to communicate to my cloud function from a chrome plugin. Everything works fine if i don't enable authentication in the cloud function console. But when i enable only authenticated user then I get the following error
Access to XMLHttpRequest at has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource
My Ajax code
return new Promise((resolve, reject) => {
$.ajax({
url : API_ENDPOINT+'method4',
method : 'POST',
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'Bearer '+firebase.auth().currentUser._lat);
},
data : 'id='+id,
success: function(data, textStatus, xhr) {
console.log(data);
resolve(data);
},
error: function(data, textStatus, xhr) {
reject(data);
console.log(data)
},
});
});
Below is my Function code deployed on cloud function
exports.method4 = functions.https.onRequest((request, response) =>{
response.set('Access-Control-Allow-Origin', 'chrome-extension://pcpjkilopmjdhcigjjndndibccdingcb');
response.set('Access-Control-Allow-Credentials', 'true');
if (request.method === 'OPTIONS') {
// Send response to OPTIONS requests
response.set('Access-Control-Allow-Methods', 'GET, POST');
response.set('Access-Control-Allow-Headers', 'Authorization');
response.set('Access-Control-Max-Age', '3600');
response.status(204).send('');
} else {
if (request.method !== 'POST') {
// Return a "method not allowed" error
return response.status(405).end();
}
return response.send(request.body['id']);
}
})
I am stuck with this for the past 2 days and not sure what is causing this issue. Thanks in advance.
It seems like your problem is because of the OPTIONS method you are using. As you can see here, the only HTTP methods supported by Google apps scripts web-application are POST and GET and OPTIONS method is currently not supported.

How to handle laravel TokenMismatchException when session expires

When the session is expired, User cant log back in without a page refresh because the _token in ajax headers is expired(AKA TokenMismatchException). I cant handle the exception by redirecting user to a log in page because the login is an overlay modal and the request is handled via ajax.
I thought i could catch the mismatch exception in Handler.php and return a json response with a session token. and on the client side, use the new token to continue the intended process. However, when i use the new token passed from server, the session token will be changed again on server side which results another TokenMismatchException.
So how should i handle the exception in a secured way without refreshing a page?
Here's what i have right now:
setup csrf_token in a global js file:
$(function () {
$.ajaxSetup({
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf_token"]').attr('content') }
});
});
render method in app/exceptions/handler.php:
public function render($request, Exception $e)
{
if ($this->isHttpException($e))
{
return $this->renderHttpException($e);
}
else if ($e instanceof TokenMismatchException)
{
if ($request->ajax()) {
return response()->json([
'message' => 'TokenMismatchException',
'token' => csrf_token()
]);
}
}
else
{
return parent::render($request, $e);
}
}
in authentication.js:
$.ajax({
type: "POST",
url: "/auth/login",
data: {
"email" : $('#login_email').val(),
"password" : $('#login_password').val(),
'remember': $('#login_remember').is(':checked')
},
success: function(response) {
if (response.message === 'TokenMismatchException') {
console.log(response); //message and token exist
//if catch the exception, use the new token to set up the ajax headers and login again
$.ajaxSettings.headers["X-CSRF-TOKEN"] = response.token;
console.log($.ajaxSettings.headers["X-CSRF-TOKEN"]);
$.ajax({
type: "POST",
url: "/auth/login",
data: {
"email" : $('#login_email').val(),
"password" : $('#login_password').val(),
'remember': $('#login_remember').is(':checked'),
},
success: function(res) {
console.log(res);
},
error: function(err) {
console.log(err);
}
});
}
console.log('logged in');
},
error: function(xhr, status, err) {
}
});
thanks in advance.
In your render function, you've to check for a specific TokenMismatchException. So may be you can try something like this:
if ($exception instanceof \Illuminate\Session\TokenMismatchException) {
return response()->json('msg', 'Your session has expired. Please try again.');
}
You may also pass a new csrf_token along with the json so that you can replace the old one with the new one and send the form request again.
if ($exception instanceof \Illuminate\Session\TokenMismatchException) {
return response()->json(['msg'=> 'Your session has expired. Please try again.', 'token'=> csrf_token()]);
}
I haven't tested this code. But this should get you started.
Also, if you want, you can use a package: https://github.com/GeneaLabs/laravel-caffeine

Ajax call getting 411 Length required error

Get request of my ajax call getting 411 length required error.
My request is working fine when token is passed via rest-client of Firefox browser
Many thanks for your help....
$.ajax(
'https://example.site.net/users/me/recent',
{
type: 'GET',
beforeSend: function (xhr) {
xhr.setRequestHeader("Content-Type","application/json");
xhr.setRequestHeader("Accept","text/json");
xhr.setRequestHeader("Authorization","Bearer token");
xhr.setRequestHeader("Access-Control-Allow-Headers", "*");
console.log('Fired prior to the request');
},
complete: function (resp) {
console.log(resp);
}
});

Unable to parse headers from successful HTTP HEAD request in jquery?

I am using the following code to get file-size of a url, the debugger shows requests to be executed with HTTP STATUS CODE 200 returning all headers including 'Content-Length' however my code outputting NULL values for headers (even after the request succeeded).
function checkURL(url) {
try {
var xhr = $.ajax({
type: "HEAD",
url: url,
async: false,
success: function (data) {
result = data;
}
});
console.log('Size :' + xhr.getResponseHeader('Content-Length'));
} catch (e) {
console.log('XHR Error :' + e);
}
}
EDIT # 1
I tested the below code and it works, however not all headers are being displayed. Once again HTTP DEBUGGER shows the elusive 'Content-Length' header to be present in reply to this XHR.
function checkURL(url) {
try {
var xhr = $.ajax({
type : "HEAD",
url : url,
complete : function (XMLHttpRequest, textStatus) {
console.log(XMLHttpRequest.getAllResponseHeaders());
}
});
} catch (e) {
console.log('Check Size XHR Error :' + e);
}
}
Whats is your type HEAD ?
it must be a xml or json !

Amplifyjs and status code

I'm trying to use "Amplifyjs" to handle AJAX requests as does John Papa in his Pluralsight course but I'm having problems with authentication.
I am using form authentication. Everything works fine.
My problem comes with the unauthenticated requests. I can not find a way to make "amplifyjs" give back to the error function the http code (401, 403 ...) to distinguish requests that failed because they were not authenticated from requests that failed because did not met the business logic.
A request example would be:
amplify.request.define("products", "ajax", {
url: "/api/Products",
datatype: "json",
type: "GET"
});
amplify.request({
resourceId: "products",
success: callbacks.success,
error: function (datos, status) {
//somecode
}
});
Thank you.
You can create a decoder if you want the XHR object and pass that along. It will have the error code and other information you may need.
amplify.request.define("products", "ajax", {
url: "http://httpstat.us/401",
datatype: "json",
type: "GET",
decoder: function ( data, status, xhr, success, error ) {
if ( status === "success" ) {
success( data, xhr );
} else if ( status === "fail" || status === "error" ) {
error( status, xhr );
} else {
error( status, xhr );
}
}
});
amplify.request({
resourceId: "products",
success: function(data, status) {
console.log(data, status);
},
error: function(status, xhr) {
console.log(status, xhr);
}
});​
You can test the above code by looking at this http://jsfiddle.net/fWkhM/
Thanks for your answer.
Finally, as I saw no one answered me I did something similar to what you propose:
var decoder = function (data, status, xhr, success, error) {
if (status === "success") {
success(data, status);
} else if (status === "fail" || status === "error") {
try {
if (xhr.status === 401) {
status = "NotAuthorized";
}
error(JSON.parse(xhr.responseText), status);
} catch (er) {
error(xhr.responseText, status);
}
}
};
After I modify the default decoder:
amplify.request.decoders._default = decoders.HeladeriaDecoder;
And in the error callback I managed the returned status.
error: function (response, status) {
if (status === "NotAuthorized") {
logger.error(config.toasts.errorNotAuthenticated);
} else {
logger.error(config.toasts.errorSavingData);
}
//more code...
}

Categories