i wanna know how i can make a pause in the system to wait the answer from the server in an AJAX request?
var method = childs[cont].getAttribute('method');
var address = childs[cont].getAttribute('address');
/*
* Making the AJAX connection
* and returning the results.
*/
phone = new ConstructorXMLHttpRequest();
onreadystatechange = function(){
switch(phone.readyState){
case 0: if(phone.readyState == 0){
break;
}
case 1: if(phone.readyState == 1){
break;
}
case 2: if(phone.readyState == 2){
break;
}
case 3: if(phone.readyState == 3){
break;
}
case 4: if(phone.readyState == 4){
if(phone.status == 200){
var val = phone.responseText;
alert([val,1]);
dataInsert(val);
break;
}
else{
alert("Problemas status:"+phone.status+" state:"+phone.readyState);
break;
}
}
}
};
phone.onreadystatechange = onreadystatechange;
if (method == 'POST'){
phone.open(method, address, true);
phone.setRequestHeader("Content-type", "multipart/form-data");
phone.send(xml2string(prepCall(childs[cont])));
}else if(method == 'GET'){
phone.open(method, address, true);
phone.setRequestHeader("Content-type", "multipart/form-data");
}
Your code looks OK. Remember AJAX is asynchronous, so instead of actually pausing, just hook a callback to your ajax request which will be executed once the request is completed.
In your case, if the request is completed successfully it will alert and execute the dateInsert function.
Related
I have a DotNetNuke application that I inherited and I'm trying to make some updates to an existing module. It happens to be a custom login module.
I'm trying to integrate 2 factor authentication. The login itself works, but when I then want to display the 2 factor fields after that, I get a 503 error on submission of the 2 factor code.
I tried to add an Application_Error event in global.asax, but that was never hit. I also tried to override the OnError event of the login control, but that is also never hit.
The OnInit is always hit during the postback that produces the 503, but not OnLoad. The strangest part is that if I step over each line of the OnInit, until I hit first thing outside of OnInit and then click Continue, everything works fine. If I just click Continue from the breakpoint at the beginning of OnInit, it will fail with a 503 before getting to OnLoad, almost every time.
This points to some kind of asynchronous error but I can't imagine what it might be.
The login versus 2 factor fields are shown and hidden by Panel controls if that makes any difference.
The message that comes back with the 503 error is "No sites currently exist for this installation."
Any suggestions on how to narrow down what's causing the 503 are greatly appreciated.
Update
I missed a log entry for a viewstate validation exception.
Validation of viewstate MAC failed. If this application is hosted by a Web
Farm or cluster, ensure that configuration specifies the same validationKey
and validation algorithm. AutoGenerate cannot be used in a cluster.
See http://go.microsoft.com/fwlink/?LinkID=314055 for more information.
I set the machine key values, but I still get the same error. Not to mention that it also doesn't explain why this only happens if I don't step through OnInit
Any thoughts?
It turns out that my problem stemmed from calling UserController.UserLogin() prior to trying to verify the 2 factor authentication.
Now that I'm calling that after the 2 factor verification, everything works as expected, and even consistently :o)
Code
Here's a sample of what changed.
This is what didn't work:
private void ValidateUser(UserInfo objUser, bool ignoreExpiring)
{
UserValidStatus validStatus = UserValidStatus.VALID;
string strMessage = Null.NullString;
DateTime expiryDate = Null.NullDate;
bool okToShowPanel = true;
validStatus = UserController.ValidateUser(objUser, PortalId, ignoreExpiring);
if (PasswordConfig.PasswordExpiry > 0)
{
expiryDate = objUser.Membership.LastPasswordChangeDate.AddDays(PasswordConfig.PasswordExpiry);
}
UserId = objUser.UserID;
//Check if the User has valid Password/Profile
switch (validStatus)
{
case UserValidStatus.VALID:
//check if the user is an admin/host and validate their IP
if (Host.EnableIPChecking)
{
bool isAdminUser = objUser.IsSuperUser || PortalSettings.UserInfo.IsInRole(PortalSettings.AdministratorRoleName); ;
if (isAdminUser)
{
if (IPFilterController.Instance.IsIPBanned(Request.UserHostAddress))
{
new PortalSecurity().SignOut();
AddModuleMessage("IPAddressBanned", ModuleMessage.ModuleMessageType.RedError, true);
okToShowPanel = false;
break;
}
}
}
//Set the Page Culture(Language) based on the Users Preferred Locale
if ((objUser.Profile != null) && (objUser.Profile.PreferredLocale != null))
{
Localization.SetLanguage(objUser.Profile.PreferredLocale);
}
else
{
Localization.SetLanguage(PortalSettings.DefaultLanguage);
}
//Set the Authentication Type used
AuthenticationController.SetAuthenticationType(AuthenticationType);
var userRequestIPAddress = new UserRequestIPAddressController();
//Complete Login
UserController.UserLogin(PortalId, objUser, PortalSettings.PortalName, userRequestIPAddress.GetUserRequestIPAddress(new HttpRequestWrapper(Request)), RememberMe);
var twoFactorAuthStatus = GetTwoFactorAuthStatus(objUser);
switch (twoFactorAuthStatus)
{
case TwoFactorAuthStatus.Error:
return;
case TwoFactorAuthStatus.NotEnabled:
RedirectUser(objUser);
break;
case TwoFactorAuthStatus.SetupNeeded:
PageNo = googleAuthSetupPageNo;
break;
case TwoFactorAuthStatus.VerificationNeeded:
PageNo = verifyGoogleAuthPageNo;
break;
}
break;
case UserValidStatus.PASSWORDEXPIRED:
strMessage = string.Format(Localization.GetString("PasswordExpired", LocalResourceFile), expiryDate.ToLongDateString());
AddLocalizedModuleMessage(strMessage, ModuleMessage.ModuleMessageType.YellowWarning, true);
PageNo = passwordPageNo;
pnlProceed.Visible = false;
break;
case UserValidStatus.PASSWORDEXPIRING:
strMessage = string.Format(Localization.GetString("PasswordExpiring", LocalResourceFile), expiryDate.ToLongDateString());
AddLocalizedModuleMessage(strMessage, ModuleMessage.ModuleMessageType.YellowWarning, true);
PageNo = passwordPageNo;
pnlProceed.Visible = true;
break;
case UserValidStatus.UPDATEPASSWORD:
AddModuleMessage("PasswordUpdate", ModuleMessage.ModuleMessageType.YellowWarning, true);
PageNo = passwordPageNo;
pnlProceed.Visible = false;
break;
case UserValidStatus.UPDATEPROFILE:
//Save UserID in ViewState so that can update profile later.
UserId = objUser.UserID;
//When the user need update its profile to complete login, we need clear the login status because if the login is from
//3rd party login provider, it may call UserController.UserLogin because they doesn't check this situation.
new PortalSecurity().SignOut();
//Admin has forced profile update
AddModuleMessage("ProfileUpdate", ModuleMessage.ModuleMessageType.YellowWarning, true);
PageNo = profilePageNo;
break;
}
if (okToShowPanel) ShowPanel();
}
This is what worked:
private void ValidateUser(UserInfo objUser, bool ignoreExpiring)
{
UserValidStatus validStatus = UserValidStatus.VALID;
string strMessage = Null.NullString;
DateTime expiryDate = Null.NullDate;
bool okToShowPanel = true;
validStatus = UserController.ValidateUser(objUser, PortalId, ignoreExpiring);
if (PasswordConfig.PasswordExpiry > 0)
{
expiryDate = objUser.Membership.LastPasswordChangeDate.AddDays(PasswordConfig.PasswordExpiry);
}
UserId = objUser.UserID;
//Check if the User has valid Password/Profile
switch (validStatus)
{
case UserValidStatus.VALID:
//check if the user is an admin/host and validate their IP
if (Host.EnableIPChecking)
{
bool isAdminUser = objUser.IsSuperUser || PortalSettings.UserInfo.IsInRole(PortalSettings.AdministratorRoleName); ;
if (isAdminUser)
{
if (IPFilterController.Instance.IsIPBanned(Request.UserHostAddress))
{
new PortalSecurity().SignOut();
AddModuleMessage("IPAddressBanned", ModuleMessage.ModuleMessageType.RedError, true);
okToShowPanel = false;
break;
}
}
}
var twoFactorAuthStatus = GetTwoFactorAuthStatus(objUser);
switch (twoFactorAuthStatus)
{
case TwoFactorAuthStatus.Error:
return;
case TwoFactorAuthStatus.NotEnabled:
LoginUser(objUser);
break;
case TwoFactorAuthStatus.SetupNeeded:
PageNo = googleAuthSetupPageNo;
break;
case TwoFactorAuthStatus.VerificationNeeded:
PageNo = verifyGoogleAuthPageNo;
break;
}
break;
case UserValidStatus.PASSWORDEXPIRED:
strMessage = string.Format(Localization.GetString("PasswordExpired", LocalResourceFile), expiryDate.ToLongDateString());
AddLocalizedModuleMessage(strMessage, ModuleMessage.ModuleMessageType.YellowWarning, true);
PageNo = passwordPageNo;
pnlProceed.Visible = false;
break;
case UserValidStatus.PASSWORDEXPIRING:
strMessage = string.Format(Localization.GetString("PasswordExpiring", LocalResourceFile), expiryDate.ToLongDateString());
AddLocalizedModuleMessage(strMessage, ModuleMessage.ModuleMessageType.YellowWarning, true);
PageNo = passwordPageNo;
pnlProceed.Visible = true;
break;
case UserValidStatus.UPDATEPASSWORD:
AddModuleMessage("PasswordUpdate", ModuleMessage.ModuleMessageType.YellowWarning, true);
PageNo = passwordPageNo;
pnlProceed.Visible = false;
break;
case UserValidStatus.UPDATEPROFILE:
//Save UserID in ViewState so that can update profile later.
UserId = objUser.UserID;
//When the user need update its profile to complete login, we need clear the login status because if the login is from
//3rd party login provider, it may call UserController.UserLogin because they doesn't check this situation.
new PortalSecurity().SignOut();
//Admin has forced profile update
AddModuleMessage("ProfileUpdate", ModuleMessage.ModuleMessageType.YellowWarning, true);
PageNo = profilePageNo;
break;
}
if (okToShowPanel) ShowPanel();
}
I changed RedirectUser() from the first example, to a LoginUser() that also performs the redirect. The LoginUser() is also called after a successful 2 factor authentication and/or setup as well.
This is a more secure way to handle this in general. The debugging feedback I was receiving was just super frustratingly misleading.
I want to wait until ajax call complete. Below I wrote general method. But It seems that is not work.
When I ran call function every afterajax request , isLoaded always to be true.
In protractor, Is there any solution? Or where have I made mistake?
Thank you
module.waitUntilJqueryLoad = async function (timeout) {
var isDone = false;
timeout = timeout || 60;
await browser.sleep(1000);
//Wait for jQuery to load
var isLoaded = await browser.driver.executeScript("return jQuery.active == 0;");
if(isLoaded) {
console.log("JQuery is Ready!");
return await browser;
}
//This loop will rotate for 60 times to check If page Is ready after every 1 second.
//You can replace your value with 60 If you wants to Increase or decrease wait time.
for (var i = 0; i < timeout; i++) {
try {
await browser.sleep(1000);
} catch (err) {}
//To check page ready state.
var isLoaded = await browser.driver.executeScript("return jQuery.active == 0;");
console.log(isLoaded);
if(isLoaded) {
console.log("JQuery is Ready");
isDone = true;
} else {
console.log("JQuery is NOT Ready !!");
}
if(isDone)
break;
}
return browser;
};
I have a work around for that. If your loading popup added display style, it will work.
This is not a general solution but other posted solution has not worked even below code.
await browser.wait(until.invisibilityOf(element(by.id('loadingPanel'))), 60000);
Example Usage :
element(by.id('selectPerson')).waitForInvisibilityOf(10000); // wait 10 seconds
Here is my solution;
protractor.ElementFinder.prototype.waitForInvisibilityOf = async function (timeout) {
var _debug = true;
var isDone = false;
timeout = timeout || 60000;
var seconds = timeout / 1000;
if(await !this.isPresent())
return this;
//This loop will rotate for 60 times to check If page Is ready after every 1 second.
//You can replace your value with 60 If you wants to Increase or decrease wait time.
for (var i = 1; i <= seconds; i++) {
await browser.sleep(1000);
var style = await this.getAttribute('style');
var insibilityOf = await style.includes('display: none;');
var visibilityOf = await style.includes('display: block;');
if(insibilityOf) {
if(_debug)
console.log(i + " second: Element invisible!");
isDone = true;
}
else {
if(_debug)
console.log(i + " second: Element NOT invisible!");
}
if(seconds === i)
throw "Element invisibility timed out after "+ timeout +" milliseconds";
if(!insibilityOf && !visibilityOf && i > 10) // break for paging is loaded
break;
if(isDone) // If element is invisible
break;
}
return await this; };
I use Xamarin-CrossDownloadManager (https://github.com/SimonSimCity/Xamarin-CrossDownloadManager) and I need waiting for download a file. I have this code:
private static async Task<bool> FileDownloadedTest(string LinkToFile, string PathFile)
{
var downloadManager = CrossDownloadManager.Current;
CrossDownloadManager.Current.PathNameForDownloadedFile = new System.Func<IDownloadFile, string>(file => {
return PathFile;
});
{
await DeleteFile(PathFile);
var file = downloadManager.CreateDownloadFile(LinkToFile);
await Task.Run(() => downloadManager.Start(file, true)); //why this not wait???
}
bool FileExist = await IsFileExist(PathFile);
return FileExist;
}
Why it not wait for finish download action? How to do it?
On library site they wrote, that I can watch the IDownloadManager.Queue to get information when the file is downloaded. But, I don't know how to use this in my method... Can you help me?
PS: Sorry for my english, I'm still learning it ;)
With that library, there is no callback or event published for when a file is finished downloading, but you can do a simple check and wait some more loop.
await Task.Run(async () =>
{
var downloadManager = CrossDownloadManager.Current;
var file = downloadManager.CreateDownloadFile(someFileBasedUrl);
downloadManager.Start(file);
bool isDownloading = true;
while (isDownloading)
{
await Task.Delay(10 * 1000);
isDownloading = IsDownloading(file);
}
});
The IsDownloading method:
bool IsDownloading(IDownloadFile file)
{
if (file == null) return false;
switch (file.Status)
{
case DownloadFileStatus.INITIALIZED:
case DownloadFileStatus.PAUSED:
case DownloadFileStatus.PENDING:
case DownloadFileStatus.RUNNING:
return true;
case DownloadFileStatus.COMPLETED:
case DownloadFileStatus.CANCELED:
case DownloadFileStatus.FAILED:
return false;
default:
throw new ArgumentOutOfRangeException();
}
}
Re: https://github.com/SimonSimCity/Xamarin-CrossDownloadManager/blob/develop/Sample/DownloadExample/Downloader.cs#L46
I don't know why IDownloadFile.Status = COMPLETED not working, but i found solve problem:
await Task.Run(() =>
{
var downloadManager = CrossDownloadManager.Current;
var file = downloadManager.CreateDownloadFile(LinkToFile);
downloadManager.Start(file);
while (file.Status == DownloadFileStatus.INITIALIZED)
{
while (file.TotalBytesExpected > file.TotalBytesWritten)
{
Debug.WriteLine(file.Status);
}
}
});
Somebody know why DownloadFileStatus.INITIALIZED working, but DownloadFileStatus.COMPLETED not?
SushiHangover's answer above worked great, and I combined it with ACR User Dialog's package (https://github.com/aritchie/userdialogs) to show a nice loading progress screen to the user while waiting for the download to complete. This works nicely on Android (I couldn't test iOS yet).
...
var downloadManager = CrossDownloadManager.Current;
var fileToDownload = downloadManager.CreateDownloadFile(args.Url);
downloadManager.Start(fileToDownload, true);
args.Cancel = true;
UserDialogs.Instance.Progress("Downloading").Show();
bool isDownloading = true;
while (isDownloading)
{
await Task.Delay(100);
if (fileToDownload.TotalBytesExpected > 0)
{
UserDialogs.Instance.Progress().PercentComplete = (int)(fileToDownload.TotalBytesWritten / fileToDownload.TotalBytesExpected * 100);
Console.WriteLine(("DOWNLOAD PROGRESS: " + fileToDownload.TotalBytesWritten / fileToDownload.TotalBytesExpected * 100).ToString() + "%");
}
isDownloading = IsDownloading(fileToDownload);
}
UserDialogs.Instance.Progress().Hide();
//Below code opens the download location after download has completed.
Intent intent = new Intent(DownloadManager.ActionViewDownloads);
intent.AddFlags(ActivityFlags.NewTask);
Android.App.Application.Context.StartActivity(intent);
return;
}
}
}
bool IsDownloading(IDownloadFile file)
{
if (file == null) return false;
switch (file.Status)
{
case DownloadFileStatus.INITIALIZED:
case DownloadFileStatus.PAUSED:
case DownloadFileStatus.PENDING:
case DownloadFileStatus.RUNNING:
return true;
case DownloadFileStatus.COMPLETED:
case DownloadFileStatus.CANCELED:
case DownloadFileStatus.FAILED:
return false;
default:
throw new ArgumentOutOfRangeException();
}
}
.append(function(d,i) {
switch (tabData.list[tabNo].type) {
case 'actl':
// return a div() chain .attr/.property/.on
var v = document.createElement("div");
var v1 = d3.select(v)
.append("h3")
.html("HFree");
return v1;
//return document.createElement("div");
break;
case 'fc':
// return a div() chain .attr/.property/.on
return document.createElement("div");
break;
case 't':
// return a div().attr/.property/.on
return document.createElement("div");
break;
}
})
.append() takes either a string 'div or function that returns created element. How do I continue the chain within the switch as in // return a div() chain .attr/.property/.on? I have edited the first case statement to one of the things I tried that does not work in order to explain better.
I use my own custom AJAX library (I'm not interested in using jQuery, etc.), which is working flawlessly in the following browsers:
Firefox 7
Chrome 14
IE 8
IE 8 (compatibility mode)
Using my custom AJAX library in the aforementioned browsers, I can make as many AJAX requests as I want, in any order, using GET and/or POST methods, and they all work flawlessly. Since a new AJAX object is created for every request (see code below), I can even have more than one AJAX request process simultaneously with success.
However, in Safari 5 an AJAX POST request only passes POST data to the server if it is the absolute first AJAX request to execute. Even if I execute the exact same AJAX POST request twice in a row, the POST data is only passed to the server during the first request. Here is the JavaScript in my custom AJAX library:
if (!Array.indexOf)
{
Array.prototype.indexOf = function(obj) { for (var i = 0; i < this.length; i++) { if (this[i] == obj) { return i; } } return -1; };
}
function ajaxObject()
{
if (window.ActiveXObject)
{
var activexmodes = ["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"];
for (var i = 0; i < activexmodes.length; i++)
{
try
{
return new ActiveXObject(activexmodes[i]);
}
catch (e)
{
}
}
}
else if (window.XMLHttpRequest)
{
return new XMLHttpRequest();
}
else
{
return false;
}
}
function ajaxRequest(aURI, aContainerId, aPostData, aResponseType, aAvoidBrowserCache)
{
// Initialize
var xmlhttp = new ajaxObject();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
if (aResponseType != "eval" && aResponseType != "EVAL")
{
// Show HTML for response
document.getElementById(aContainerId).innerHTML = xmlhttp.responseText;
}
else
{
// Parse & execute JavaScript for response
var responseText = xmlhttp.responseText;
var startPos, endPos;
for (var i = 0; i < responseText.length; i++)
{
if (responseText.substring(i, i + 6) == "<eval>")
{
startPos = i + 6;
break;
}
}
for (var i = startPos; i < responseText.length; i++)
{
if (responseText.substring(i, i + 7) == "</eval>")
{
endPos = i;
break;
}
}
textToEval = responseText.substring(startPos, endPos);
eval(textToEval);
}
}
else
{
try
{
if (xmlhttp.status != 0 && xmlhttp.status != 200)
{
alert('Error ' + xmlhttp.status);
}
}
catch (e)
{
// Handle IE8 debug "unknown error"
}
}
}
if (aAvoidBrowserCache != false)
{
// Combat browser caching:
aURI = aURI + (aURI.indexOf("?") == -1 ? "?" : "&");
theTime = new Date().getTime();
aURI = aURI + theTime + "=" + theTime;
}
// Make request
if (typeof aPostData == "undefined" || aPostData == null || aPostData == "")
{
// GET request
xmlhttp.open("GET", aURI, true);
xmlhttp.send();
}
else
{
// POST request
var parameters = "";
if (aPostData.constructor.toString().indexOf("Array") != -1)
{
// Use parameters passed as array
for (var postCount = 0; postCount < aPostData.length; postCount++)
{
if (parameters != "")
{
parameters = parameters + "&";
}
parameters = parameters + aPostData[postCount][0] + "=" + encodeURIComponent(aPostData[postCount][1]);
}
}
else
{
// Use parameters passed as string
parameters = aPostData;
}
xmlhttp.open("POST", aURI, true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send(parameters);
}
}
So for example, either of the following AJAX POST requests will pass POST data if they are the absolute first AJAX request (whether GET or POST); otherwise, the POST data is not passed:
ajaxRequest("test.aspx", "", [["name1","value1"],["name2","value2"]], "eval");
or
ajaxRequest("test.aspx", "", "name1=value1&name2=value2", "eval");
I have added debug statements all throughout my AJAX library, and the POST parameters are being created in the "parameters" variable as expected prior to each POST request. I have absolutely no idea why, only in Safari 5 (out of the mentioned browsers), I have this problem. Any ideas?
Thanks in advance!
Jesse
The reason the call is failing is because of a bug in Safari when working with Windows Authentication under IIS. Go to the Authentication settings of your website. Right click on Windows Authentication, choose providers and remove Negotiate, leaving NTLM which works fine. I haven't tested Kerberos.
This issue only appears in certain builds of safari.
Came here from the thread you mentioned might be a dupe. I never solved our problem, but have you tried a simple page making post requests? With our issue it's a post problem, not an AJAX problem, we're still stumped though.
What version of IIS are you running on the server?
I can confirm that the problem seems related to some sort of interaction between Safari & IIS. Luckily, I only develop and test this portion of the code on Windows. I moved it unchanged to a LAMP (Linux/Apache) staging server (prior to moving to our LAMP production server) and the problem went away. I was seeing the problem with Safari 5, IIS 5.1, & an ActiveState Perl 5.6 CGI.
Under RHEL 5, Apache 2.2, & Perl 5.8, it is gone.