Override Ext.data.Connection - Best Practice - javascript

I need to override Ext.data.Connection to show a Login Form.
I do this at the moment in Ext.application.launch which works as expected.
Is it possible to swap this piece of code somewhere different like in an extra file?

If you need this only to recognize when user is not authenticated you might want to consider doing something else. Like adding a handler to Ajax singleton:
function addAjaxErrorHandler(object) {
Ext.Ajax.on('requestexception', function(conn, response, options, e) {
var statusCode = response.status,
errorText = null,
captionText = response.statusText;
// 404 - file or method not found - special case
if (statusCode == 404) {
Ext.MessageBox.alert('Error 404', 'URL ' + response.request.options.url + ' not found');
return;
}
if (response.responseText != undefined) {
var r = Ext.decode(response.responseText, true);
if (r != null) {
// 401 - not authenticated. For some reason we don't have authentication cookie anymore
if (r.ErrorCode == 401) {
Ext.MessageBox.alert('Error', 'You must log in to use application',
function() {
// do something when user is not authenticated
object);
return;
}
errorText = r.ErrorMessage;
}
if (errorText == null)
errorText = response.responseText;
}
if (!captionText)
captionText = 'Error ' + statusCode;
Ext.MessageBox.alert(captionText, errorText);
},
object);
}
Then just call this function from your application.launch() function and pass application object so the scope if defined.

Related

Why if and else both condition executing at same time in JavaScript | If and Else Condition

Why If and else condition work both in JavaScript. if (xhr.readyState == 4 && xhr.status == 200)
I am working on php MVC project.
I created a profile edit page in background JavaScript If and Else both code executing. profile edit Successfully but else code work and it's show error "Sorry, this content isn't available right now".
why this else condition work??
same This code work in login and registration page.
save in local file and run than it work :-
online code
Code
document.querySelector("#Profile_Save").addEventListener("click", () => {
if (document.querySelector("#Profile_Edit_Email").value.match(/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+#[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/)) {
document.querySelector("#Profile_Edit_Msg").classList.remove("active_success");
document.querySelector("#Profile_Edit_Msg").classList.remove("active_denger");
document.querySelector("#Profile_Save").innerHTML = "Loading...";
document.querySelector("#Profile_Save").classList.remove("active");
document.querySelector("#Profile_Save").disabled = true;
document.querySelector("#Profile_Edit_F_Name").disabled = true;
document.querySelector("#Profile_Edit_L_Name").disabled = true;
document.querySelector("#Profile_Edit_Email").disabled = true;
var f_name = document.querySelector("#Profile_Edit_F_Name").value,
l_name = document.querySelector("#Profile_Edit_L_Name").value,
email = document.querySelector("#Profile_Edit_Email").value;
var xhr = new XMLHttpRequest();
xhr.open("POST", "Api/ProfileEdit", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) { // this one if executing
var json = JSON.parse(xhr.responseText);
if (json.Status == "Ok") {
window.location.href = "Profile"; // it also work
} else {
document.querySelector("#Profile_Edit_Msg").classList.remove("active_success");
document.querySelector("#Profile_Edit_Msg").classList.add("active_denger");
document.querySelector("#Profile_Edit_Msg").innerHTML = json.Message;
}
} else { // this one else executing
document.querySelector("#Profile_Edit_Msg").classList.add("active_denger");
document.querySelector("#Profile_Edit_Msg").innerHTML = "Sorry, this content isn't available right now"; // this message show
}
}
xhr.send("F_Name=" + f_name + "&L_Name=" + l_name + "&Email=" + email);
document.querySelector("#Profile_Save").innerHTML = "Register";
document.querySelector("#Profile_Save").classList.add("active");
document.querySelector("#Profile_Save").disabled = false;
document.querySelector("#Profile_Edit_F_Name").disabled = false;
document.querySelector("#Profile_Edit_L_Name").disabled = false;
document.querySelector("#Profile_Edit_Email").disabled = false;
} else {
document.querySelector("#Profile_Edit_Msg").classList.add("active_denger");
document.querySelector("#Profile_Edit_Msg").innerHTML = "Invalid Email Address!";
}
});
return JSON
{"Status":"Ok","Message":"Profile Edit Successfully!"}
Output
open profile page and
error message:- "Sorry, this content isn't available right now"
help me!
Thank you!!
The readystatechange event fires multiple times.
Value State Description
0 UNSENT Client has been created. open() not called yet.
1 OPENED open() has been called.
2 HEADERS_RECEIVED send() has been called, and headers and status are available.
3 LOADING Downloading; responseText holds partial data.
4 DONE The operation is complete.
Your
if (xhr.readyState == 4 && xhr.status == 200) {
branch will only be entered into at the end of a request, if the request was successful. But earlier, while the request is still ongoing, other state changes will occur, and the else branch will be entered into.
Instead, only do anything if the readyState is 4 - and, when it is 4, you can parse the response, or populate the #Profile_Edit_Msg to say there was a problem.
Other improvements:
Save the Profile_Edit_Msg in a variable instead of repetitively selecting it over and over again
Use strict equality, not sloppy equality
Use .textContent when assigning text to an element - only use .innerHTML when inserting HTML markup
JSON is a particular format of a string that can be deserialized into an object or other value. JSON.parse does not return JSON - JSON.parse is called with a JSON-formatted string and returns an object. Call your json variable something else.
denger looks misspelled - did you mean danger? (Typos are a common problem in programming - better to fix them earlier than later)
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) {
return;
}
const profile = document.querySelector("#Profile_Edit_Msg");
if (xhr.status === 200) {
const result = JSON.parse(xhr.responseText);
if (result.Status === "Ok") {
window.location.href = "Profile";
} else {
profile.classList.remove("active_success");
profile.classList.add("active_denger");
profile.innerHTML = json.Message;
}
} else {
profile.classList.add("active_denger");
profile.textContent = "Sorry, this content isn't available right now";
}
};
You could also consider using the fetch API instead of XMLHttpRequest - fetch is a bit nicer to work with and has been supported in all modern browsers for ages.

Javascript capture errors

I'm using window.error to try to capture all client side errors.
It's working fine with Javascript errors but It doesn't capture all errors like Network Errors, or AJAX errors.
This is my code (I can't use jQuery, so is not possible to use .ajaxError):
window.onerror = function(messageOrEvent, source, lineno, colno, error) {
console.log("Captured: " + messageOrEvent)
}
This is the result:
Anyone knows a way to capture ALL errors on the client side?
Thanks
Maybe hook over the default request object:
(function(orig){
window.XMLHttpRequest=function(...args){
var instance=new orig(...args);
instance.addEventListener("readyStateChange",function(){
if(instance.status!==200){
throw new Error(instance.status+":"+instance.statusText);
}
});
return instance;
};
})(XMLHttpRequest);
I've found a way. This is my code. I think that this capture all errors.
// JavaScript Errors
window.onerror = function(messageOrEvent, source, lineno, colno, error) {
console.log("Captured: " + messageOrEvent)
}
// 404 FILES
window.addEventListener('error', function(e) {
console.log(e);
}, true);
// AJAX Errors
var open = window.XMLHttpRequest.prototype.open,
send = window.XMLHttpRequest.prototype.send;
function openReplacement(method, url, async, user, password) {
this._url = url;
return open.apply(this, arguments);
}
function sendReplacement(data) {
if(this.onreadystatechange) {
this._onreadystatechange = this.onreadystatechange;
}
this.onreadystatechange = onReadyStateChangeReplacement;
return send.apply(this, arguments);
}
function onReadyStateChangeReplacement() {
// CAPTURE HERE.
if(this.status != 200){
console.log(this.responseURL + " " + this.status + " " + this.statusText);
}
if(this._onreadystatechange) {
return this._onreadystatechange.apply(this, arguments);
}
}
window.XMLHttpRequest.prototype.open = openReplacement;
window.XMLHttpRequest.prototype.send = sendReplacement;

Telegram API returning HTML instead of JSON

I'm writing a telegram bot to report fail2ban bans. It's very simple and dirty, written hastily, but it can be used to report any message to a single telegram user:
var TelegramBot = require('node-telegram-bot-api');
var fs = require('fs');
var store = {
get: function (key) {
return fs.readFileSync(__dirname + '/' + key, { encoding: 'utf-8' });
},
set: function (key, value) {
fs.writeFileSync(__dirname + '/' + key, value, { encoding: 'utf-8' });
}
};
var token = store.get('token');
var args = process.argv.slice(2);
if (args.length == 0) {
console.error('No mode specified');
process.exit(0);
}
TelegramBot.prototype.unregisterText = function (regexp) {
for (var i = 0; i < bot.textRegexpCallbacks.length; ++i) {
if (bot.textRegexpCallbacks[i].regexp.toString() == regexp) {
bot.textRegexpCallbacks.splice(i, 1);
return;
}
}
};
fs.appendFileSync(__dirname + '/logs',
'[' + (new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '')) + '] '
+ args.join(' ') + '\n',
{ encoding: 'utf-8' });
switch (args[0]) {
case 'setup':
var bot = new TelegramBot(token, { polling: true });
var step = 'none';
bot.onText(/\/setup/, function (msg, match) {
var fromId = msg.from.id;
step = 'setup-started';
bot.sendMessage(fromId, 'Starting setup. Please enter the verification key.');
bot.onText(/(.+)/, function (msg, match) {
if (step == 'setup-started') {
var key = match[1];
var verification = store.get('key');
if (key == verification) {
store.set('owner', msg.from.id);
step = 'verified';
bot.sendMessage(msg.from.id, 'Correct. Setup complete.');
} else {
step = 'none';
bot.unregisterText(/(.+)/);
bot.sendMessage(msg.from.id, 'Wrong. Setup aborted.');
}
}
});
});
break;
case 'report':
var bot = new TelegramBot(token, { polling: false });
var owner = store.get('owner');
var subject = args[1];
if (subject == 'message') {
var message = args.slice(2).join(' ');
bot.sendMessage(owner, message);
} else if (subject == 'file') {
var content = fs.readFileSync(args[2], { encoding: 'utf-8' });
bot.sendMessage(owner, content);
}
break;
default:
console.error('Unrecognized mode', args[0]);
break;
}
On my developer machine it works fine. I invoke:
node bot.js report message whatever message i want
And I correctly received "whatever message i want" on telegram. However, once I gitted it on my digitalocean vps, it no longer worked. It turns out the problem is with the telegram library:
Unhandled rejection Error: Error parsing Telegram response: <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Bots: An introduction for developers</title>
...
Which apparently returns an html page instead of json... I also tried to contact the same endpoint (api.telegram.org/bothash/sendMessage) with curl on my vps and it returned json (with an error message because i didnt send any parameters, but still json).
I cannot fathom why this happens. Any help?
It seems like either you don't have a file with token on your VPN or the token is incorrect.
You can check it by yourself:
When you make a request to api.telegram.org/{token}/sendMessage, and {token} is incorrect, it redirects you to this page, which responds with HTML you've mentioned in your question.
So you have to debug a behavior of your store.get and store.get functions along with files and tokens to make sure you are using a correct one.
Also, I'd recommend to run bot.getMe() before using any other Telegram API methods to ensure you specified a correct bot token.

get text from page and put it into a variable

I want to extend a facebook access token using the method below:
function extend(fb_access_token) {
var extendingUrl;
try{
console.log("Extending Facebook Access Token.");
if (app_id == "" || app_id == null) {
alert("App ID not configured properly.");
hasError = true;
return;
} else {
hasError = false;
}
if (app_secret == "" || app_secret == null) {
alert("App Secret not configured properly.");
hasError = true;
return;
} else {
hasError = false;
}
if (fb_access_token == "" || fb_access_token == null) {
alert("Facebook Access Token not was not generated.");
hasError = true;
return;
} else {
hasError = false;
}
if(hasError) {
alert("URL not formed.");
} else {
extendingUrl = "https://graph.facebook.com/oauth/access_token?client_id="+app_id+"&client_secret="+app_secret+"&grant_type=fb_exchange_token&fb_exchange_token="+fb_access_token;
window.location.replace = extendingUrl;
console.log("Facebook Access Token successfully extended.");
}
} catch (OAuthException) {
console.log("Login status or access token has expired, been revoked, or is otherwise invalid.");
}
}
I want to get the generated access token from the page that will eventually give the extended access token, see var extendingUrl.
The page will return something like:
access_token=CAAERkjuisOYBALHbBZB9oq01ybCoyBfyGlSHtkkZBDqDvevrWZC42JwMawxxxOxQsiKHMNVPHZCbh3ntF7GdnYwnq3BLTh6ZA2YUJCVSh8QA5nEZACZCXVtZCL5RZC72pl3afKMAOMG2WGKtjnD1GJTjQEPC2XH3X1ycr3GeAUWBShDj7ojFVCWhDe6jBGvBu2nn7Ohu9C2udBoamOBxoQFun&expires=5182005
and I will substring the string above and eliminate access_token= and &expires=5182005 to a new variable, and store it into my database.
Got it. I used jquery and fed the url (extendingUrl), in return, it gave me the contents of the url I requested. Then I used regex and substring to eliminate the unwanted text.
$.get(extendingUrl, function(data) {
var raw = data;
var patt1 = /(access_token=)(.*)(?=&expires=)/;
var result = raw.match(patt1);
var longToken = result[0].substring(13, 400);
});

Form submit using Ajax

I need to submit the a form using Ajax with POST method.The code is as follows,
function persistPage(divID,url,method){
var scriptId = "inlineScript_" + divID;
var xmlRequest = getXMLHttpRequest();
xmlRequest.open("POST",url,true);
xmlRequest.onreadystatechange = function(){
alert(xmlRequest.readyState + " :" + xmlRequest.status);
if (xmlRequest.readyState ==4 || xmlRequest.status == 200)
document.getElementById(divID).innerHTML=xmlRequest.responseText;
};
xmlRequest.open("POST", url, false);
alert(xmlRequest.readyState);
xmlRequest.send(null);
}
but the form is not submitting(request is not executed or no data posted).How to submit the form using Ajax.
Thanks
There's a few reasons why your code doesn't work. Allow me to break it down and go over the issues one by one. I'll start of with the last (but biggest) problem:
xmlRequest.send(null);
My guess is, you've based your code on a GET example, where the send method is called with null, or even undefined as a parameter (xhr.send()). This is because the url contains the data in a GET request (.php?param1=val1&param2=val2...). When using post, you're going to have to pass the data to the send method.
But Let's not get ahead of ourselves:
function persistPage(divID,url,method)
{
var scriptId = "inlineScript_" + divID;
var xmlRequest = getXMLHttpRequest();//be advised, older IE's don't support this
xmlRequest.open("POST",url,true);
//Set additional headers:
xmlRequest.setRequestHeader('X-Requested-With', 'XMLHttpRequest');//marks ajax request
xmlRequest.setRequestHeader('Content-type', 'application/x-www-form-urlencode');//sending form
The first of the two headers is not always a necessity, but it's better to be safe than sorry, IMO. Now, onward:
xmlRequest.onreadystatechange = function()
{
alert(xmlRequest.readyState + " :" + xmlRequest.status);
if (xmlRequest.readyState ==4 || xmlRequest.status == 200)
document.getElementById(divID).innerHTML=xmlRequest.responseText;
};
This code has a number of issues. You're assigning a method to an object, so there's no need to refer to your object using xmlRequest, though technically valid here, this will break once you move the callback function outside the persistPage function. The xmlRequest variable is local to the function's scope, and cannot be accessed outside it. Besides, as I said before, it's a method: this points to the object directlyYour if statement is a bit weird, too: the readystate must be 4, and status == 200, not or. So:
xmlRequest.onreadystatechange = function()
{
alert(this.readyState + " :" + this.status);
if (this.readyState === 4 && this.status === 200)
{
document.getElementById(divID).innerHTML=this.responseText;
}
};
xmlRequest.open("POST", url, false);
alert(xmlRequest.readyState);//pointless --> ajax is async, so it will alert 0, I think
xmlRequest.send(data);//<-- data goes here
}
How you fill the data is up to you, but make sure the format matches the header: in this case 'content type','x-www-form-urlencode'. Here's a full example of just such a request, it's not exactly a world beater, since I was in the process of ditching jQ in favour of pure JS at the time, but it's serviceable and you might pick up a thing or two. Especially take a closer look at function ajax() definition. In it you'll see a X-browser way to create an xhr-object, and there's a function in there to stringify forms, too
POINTLESS UPDATE:
Just for completeness sake, I'll add a full example:
function getXhr()
{
try
{
return XMLHttpRequest();
}
catch (error)
{
try
{
return new ActiveXObject('Msxml2.XMLHTTP');
}
catch(error)
{
try
{
return new ActiveXObject('Microsoft.XMLHTTP');
}
catch(error)
{
//throw new Error('no Ajax support?');
alert('You have a hopelessly outdated browser');
location.href = 'http://www.mozilla.org/en-US/firefox/';
}
}
}
}
function formalizeObject(form)
{//we'll use this to create our send-data
recursion = recursion || false;
if (typeof form !== 'object')
{
throw new Error('no object provided');
}
var ret = '';
form = form.elements || form;//double check for elements node-list
for (var i=0;i<form.length;i++)
{
if (form[i].type === 'checkbox' || form[i].type === 'radio')
{
if (form[i].checked)
{
ret += (ret.length ? '&' : '') + form[i].name + '=' + form[i].value;
}
continue;
}
ret += (ret.length ? '&' : '') + form[i].name +'='+ form[i].value;
}
return encodeURI(ret);
}
function persistPage(divID,url,method)
{
var scriptId = "inlineScript_" + divID;
var xmlRequest = getXhr();
xmlRequest.open("POST",url,true);
xmlRequest.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xmlRequest.setRequestHeader('Content-type', 'application/x-www-form-urlencode');
xmlRequest.onreadystatechange = function()
{
alert(this.readyState + " :" + this.status);
if (this.readyState === 4 && this.status === 200)
{
document.getElementById(divID).innerHTML=this.responseText;
}
};
xmlRequest.open("POST", url, false);
alert(xmlRequest.readyState);
xmlRequest.send(formalizeObject(document.getElementById('formId').elements));
}
Just for fun: this code, untested, but should work allright. Though, on each request the persistPage will create a new function object and assign it to the onreadystate event of xmlRequest. You could write this code so that you'll only need to create 1 function. I'm not going into my beloved closures right now (I think you have enough on your plate with this), but it's important to know that functions are objects, and have properties, just like everything else:Replace:
xmlRequest.onreadystatechange = function()
{
alert(this.readyState + " :" + this.status);
if (this.readyState === 4 && this.status === 200)
{
document.getElementById(divID).innerHTML=this.responseText;
}
};
With this:
//inside persistPage function:
xmlRequest.onreadystatechange = formSubmitSuccess;
formSubmitSuccess.divID = divID;//<== assign property to function
//global scope
function formSubmitSuccess()
{
if (this.readyState === 4 && this.status === 200)
{
console.log(this.responseText);
document.getElementById(formSubmitSuccess.divID).innerHTML = this.responseText;
//^^ uses property, set in persistPAge function
}
}
Don't use this though, as async calls could still be running while you're reassigning the property, causing mayhem. If the id is always going to be the same, you can, though (but closures would be even better, then).
Ok, I'll leave it at that
This code can let you understand. The function SendRequest send the request and build the xmlRequest through the GetXMLHttpRequest function
function SendRequest() {
var xmlRequest = GetXMLHttpRequest(),
if(xmlRequest) {
xmlRequest.open("POST", '/urlToPost', true)
xmlRequest.setRequestHeader("connection", "close");
xmlRequest.onreadystatechange = function() {
if (xmlRequest.status == 200) {
// Success
}
else {
// Some errors occured
}
};
xmlRequest.send(null);
}
}
function GetXMLHttpRequest() {
if (navigator.userAgent.indexOf("MSIE") != (-1)) {
var theClass = "Msxml2.XMLHTTP";
if (navigator.appVersion.indexOf("MSIE 5.5") != (-1)) {
theClass = "Microsoft.XMLHTTP";
}
try {
objectXMLHTTP = new ActivexObject(theClass);
return objectXMLHTTP;
}
catch (e) {
alert("Errore: the Activex will not be executed!");
}
}
else if (navigator.userAgent.indexOf("Mozilla") != (-1)) {
objectXMLHTTP = new XMLHttpRequest();
return objectXMLHTTP;
}
else {
alert("!Browser not supported!");
}
}
take a look at this page. In this line: req.send(postData); post data is an array with values that should be posted to server. You have null there. so nothing is posted. You just call request and send no data. In your case you must collect all values from your form, as XMLHTTPRequest is not something that can simply submit form. You must pass all values with JS:
var postData = {};
postData.value1 = document.getElementById("value1id").value;
...
xmlRequest.send(postData);
Where value1 will be available on server like $_POST['value'] (in PHP)
Also there might be a problem with URL or how you are calling persistPage. persistPage code looks ok to me, but maybe I'm missing something. Also you can take a look if you have no errors in console. Press F12 in any browser and find console tab. In FF you may need to install Firebug extention. Also there you will have Network tab with all requests. Open Firebug/Web Inspector(Chrome)/Developer Toolbar(IE) and check if new request is registered in its network tab after you call persistPage.
I found you've invoked the
xmlRequest.open()
method twice, one with async param as true and the other as false. What exactly do you intend to do?
xmlRequest.open("POST", url, true);
...
xmlRequest.open("POST", url, false);
If you want to send asynchronous request, pls pass the param as true.
And also, to use 'POST' method, you'd better send the request header as suggested by Elias,
xmlRequest.setRequestHeader('Content-type', 'application/x-www-form-urlencode');
Otherwise, you may still get unexpected issues.
If you want a synchronous request, actually you may handle the response directly right after you send the request, just like:
xmlRequest.open("POST", url, false);
xmlRequest.send(postData);
// handle response here
document.getElementById(scriptId).innerHTML = xmlRequest.responseText;
Hope this helps.

Categories

Resources