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...
}
Related
So I am using the JavaScript port of RiveScript which uses ajax and of course I don't want to use jQuery anymore. There is only one line ajax and I want to change it to the new Fetch API.
**FYI: You can see the ajax code in line 1795 of the CDN.**
So here's the original code:
return $.ajax({
url: file,
dataType: "text",
success: (function(_this) {
return function(data, textStatus, xhr) {
_this.say("Loading file " + file + " complete.");
_this.parse(file, data, onError);
delete _this._pending[loadCount][file];
if (Object.keys(_this._pending[loadCount]).length === 0) {
if (typeof onSuccess === "function") {
return onSuccess.call(void 0, loadCount);
}
}
};
})(this),
error: (function(_this) {
return function(xhr, textStatus, errorThrown) {
_this.say("Ajax error! " + textStatus + "; " + errorThrown);
if (typeof onError === "function") {
return onError.call(void 0, textStatus, loadCount);
}
};
})(this)
});
and here's what I tried so far using the Fetch API:
return fetch(file, {
dataType: "text"
})
.then(function(_this) {
return function(data, textStatus, xhr) {
_this.say("Loading file " + file + " complete.");
_this.parse(file, data, onError);
delete _this._pending[loadCount][file];
if (Object.keys(_this._pending[loadCount]).length === 0) {
if (typeof onSuccess === "function") {
return onSuccess.call(void 0, loadCount);
}
}
};
})
.catch(function(_this) {
return function(xhr, textStatus, errorThrown) {
_this.say("Ajax error! " + textStatus + "; " + errorThrown);
if (typeof onError === "function") {
return onError.call(void 0, textStatus, loadCount);
}
};
})
The app code:
var bot = new RiveScript();
bot.loadFile("./brain.rive", loading_done, loading_error);
function loading_done (batch_num) {
console.log("Batch #" + batch_num + " has finished loading!");
bot.sortReplies();
var reply = bot.reply("local-user", "Hello, bot!");
console.log("The bot says: " + reply);
}
function loading_error (error) {
console.log("Error when loading files: " + error);
}
Using the Fetch API, I'm not seeing any error now though I'm also not seeing any error or success messages.
Am I missing something here?
The fetch init object doesn’t have a dataType key.
To indicate you want plain text back, add an Accept: text/plain header to the request:
fetch(file, {
headers: {
"Accept": "text/plain"
},
})
And the fetch call returns a promise that resolves with a Response object, and that Response object provides methods that resolve with text, JSON data, or a Blob — which means the basic form for handling the response from your fetch(…) call is like this:
fetch(file, {
headers: {
"Accept": "text/plain"
},
})
.then(response => response.text())
.then(text => {
// Do something with the text
})
So you need to take the existing code in the question and fit it into that form.
I'm running a Flask server. A JS file send data to the server through POST requests. This is the server code:
#app.route('/approve', methods=['POST'])
def approve():
try:
assignmentId = request.form['assignmentId']
response = client.approve_assignment(
AssignmentId=assignmentId
)
return make_response(jsonify(response), response['ResponseMetadata']['HTTPStatusCode'])
except ClientError as e:
return make_response(jsonify(e.response), e.response['ResponseMetadata']['HTTPStatusCode'])
In JS, I want to have an alert to notify whether the action was successful or not; and if fail then what is the specific error. However, the returned data is empty and I could not check it to notify the user of specific error.
$.post("http://cronus.eecs.northwestern.edu/mturk/approve",
{assignmentId: assignmentId,
OverrideRejection: false},
function(data, status) {
console.log(data);
console.log(status);
if (status == 200) {
alert("Approved successfully");
} else {
alert("Error");
}
});
How could I fix this? Is data null because I didn't use the correct response object in Flask code?
You should use .fail for this.
$.post( "example.php", function() {
alert( "success" );
})
.done(function() {
alert( "second success" );
})
.fail(function(error) {
alert( `error ${error}` );
})
.always(function() {
alert( "finished" );
});
I hope this can help you.
var request = $.ajax({
url: url,
method: 'post',
data: {...},
});
request.done(function(message) {
alert(message);
});
request.fail(function(error) {
alert(error);
});
I have a C# web method that sometimes throws an exception when the call shown below times out (>30 seconds). This is fine I expect this behavior, but the problem is, when the ajax call hits the .fail callback, the error message states "Internal server error". I want to be able to catch the exception and report that the database timed out. How can I do this?
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static string GetSPResults(string reportId, string sproc, Dictionary<string, string> parameters, string[] ensureArrays, string[] encryptArrays, string[] dateFields)
{
...
XElement result = avdata.ExecuteSPXmlXElement(sproc, parameters, null);
...
}
$.ajax({
type: "POST",
url: "/Patrol/Report.aspx/GetSPResults",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(postData)
}).done(function (result) {
...
}).fail(function (jqXHR, textStatus, err) {
alert("An error has occurred: " + err); //rerpots "Internal server error" no matter what problem occurs server-side
});
i use this
$.ajax({
type: "POST",
url: "/Patrol/Report.aspx/GetSPResults",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(postData)
error: function (jqXHR, textStatus, errorThrown) {
mensaje = false;
if (jqXHR.status === 0) {
alert("Not connect: Verify Network.");
} else if (jqXHR.status == 404) {
alert("Requested page not found [404]");
} else if (jqXHR.status == 500) {
alert("Internal Server Error [500].");
} else if (textStatus === 'parsererror') {
alert("Requested JSON parse failed.");
} else if (textStatus === 'timeout') {
alert("Time out error.");
} else if (textStatus === 'abort') {
alert("Ajax request aborted.");
} else {
toastr.error("Uncaught Error:", "Mensaje Servidor");
}
}
});
I'm sending an ajax request to a remote api.
This is the response I receive when i'm just browsing to the URL:
{
"organizations":[],
"displayName":"Asaf Nevo",
"roles":[
{
"name":"provider",
"id":"106"
}
],
"app_id":"app_id",
"email":"email",
"id":"id"
}
Now the api is in a different ORIGIN so I needed to use JSONP in my call:
$.ajax(
{
url: KeyrockConfig.defaultInstanceUrl + uri,
type: method,
dataType: "jsonp",
data: params,
success: function (result, status, xhr) {
callback(result, status, xhr);
},
//TODO consider having a different callback for error
error: function (xhr, status, error) {
callback(error, status, xhr);
}
}
);
But I'm keep getting Uncaught SyntaxError: Unexpected token :
I tried to do:
$.ajax(
{
url: KeyrockConfig.defaultInstanceUrl + uri,
type: method,
dataType: "jsonp",
jsonp:false,
jsonpCallback: function (response) {
alert(response);
},
data: params,
success: function (result, status, xhr) {
callback(result, status, xhr);
},
//TODO consider having a different callback for error
error: function (xhr, status, error) {
callback(error, status, xhr);
}
}
);
But the alert was never called. What do I do wrong?
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();