Ajax call from Mobile browser - javascript

I have searched a lot but no solution worked for me.
I'm working on a captive portal with pfsense that means a user will need to fill out a form whenever they connect to our network before they recieve free internet. What I'm doing is taking some data from user and making an ajax Get request (using jQuery 3.2.1) to a web service (based on asp.net web api).
Everything works fine when I do it on a computer although it doesn't work on mobile browsers.
I don't know why but somehow data doesn't go to web services when we use mobile phones.
This is my javascript code.
function uploadData(){
var PhNumber = document.getElementById("customerPhone").value;
var cName = document.getElementById("customerName").value;
var Url="http://192.168.1.155/customer/api/Values?customerName="+cName+"&customerPhone="+PhNumber+"";
var exp = /^((\+92)|(92)|(0092))-{0,1}\d{3}-{0,1}\d{7}$|^\d{11}$|^\d{4}-\d{7}$/;
var cNum = exp.test(PhNumber);
if (exp.test(PhNumber)) {
$(function () {
$.ajax({
type: 'GET',
url : Url,
cache : 'false',
dataType:'xml',
success: function (responce) {
return alert("Data Saved");
},
failure: function() {
alert("Some Error Acured");
}
});
});
}
}

Related

Trying to catch Log failure and 404 with JQuery

I am working on a web Spring MVC 4 application for my end of studies project, the application should connect web and android clients.
I used #RestController to help android app communicate easily via json. I am trying to catch connection failure ex:404 in both web or mobile app, even in the web application i tried to make almost all communication with the server via Ajax hoping to make user more relaxed (Progress bars, Live info hints...) but, one of the problems in countries that after using event.preventDefault() from jQuery, i can't get over it in next actions and the response pages loaded and kept unseen! for example here is my login page example:
login.js
jQuery(document).ready(function ($) {
$("#login-form").submit(function (event) {
//Do somthing...
// Call login function
logViaAjax(event);
// Prevent the form from submitting via the browser.
return false; //Or using event.preventDefault()
});
});
// logViaAjax function
function logViaAjax(event) {
var logObj = {};
logObj["username"] = $("#username").val();
logObj["password"] = $("#password").val();
//the response
$.ajax({
type: "POST",
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
url: "/login",
data: logObj,
dataType: 'text',
timeout: 10000,
success: function (data) {
if (data.indexOf("login-box") !== -1) {
showLogFail();
}else{
window.location.reload();
//I dont need to reload the page because this gives me login page again... May be if there is a way to get the URL from data!?
}
},
error: function () {
showWarning();
}
});
I am using Spring Security 4 to handle authentification and we know that it gives url ex:/login?fail for failure and get the requested page if succeed and i recently knew that it redirect even before getting in the loginUrl my ex /login. I tried to test if the user logged in on server side and send json response but this could leads to lose the page before requesting login.
I think i should test in the success: function() if url loaded in the jQuery(but not showed) contains ?fail or not, to inform user to change log or password. Else, if it do not, the page user need is charged in the back and all what i need is to show it.
UPDATE
After those little changes all what I need to make is just to keep the page beyond the login page and reshow it. Take note that this function is automatically offered by Spring Security but it still running on background. Ex in my case when user click /messenger the app redirect him to /login to login, if he fail login it gives /login?fail but this page is unseen due to JQuery, else he login successfully it send him to /messenger again…
Try this
var flag;
jQuery(document).ready(function ($) {
$("#login-form").submit(function (event) {
//Do somthing...
// Call login function
logViaAjax(event);
if(flag.status == 404){
return false;
}
});
});
function logViaAjax(event) {
var logObj = {};
logObj["username"] = $("#username").val();
logObj["password"] = $("#password").val();
//the response
flag = $.ajax({
type: "POST",
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
url: "/login",
data: logObj,
dataType: 'text',
timeout: 10000,
success: function (data) {
//Here to move to the page unseen if success and show error hint if it fail...
},
error: function () {
showWarning(); //Show error alerts, this part is DONE!
}
});
Changes Made
► Assigned the AJAX to a variable and dded a condition in the jQuery(document).ready
AJAX - The onreadystatechange Event
Demo Fiddle to show 404 error

How to avoid rendering the initial view of browsing session when page is refreshed from somewhere else in the application using History.js?

I am trying very hard to implement history.js a jQuery plugin for IE 8 and 9. The demo seems to be fine in IE10+ and other modern browsers but I'm not able to understand the problem below for IE<=9. The demo is a asp.net mvc5 application where I want to provide a single page user experience where I'm just loading partial views and performing a post action via ajax. All the views load in a #shell div in my master view. May be I am missing something!!
My demo app starts with http://localhost:1089/ which is the first request that renders a login page. Any other pushState() causes a change in the url with appending #Home/About?ref=one.
Following is my script that is executed in layout.cshtml which is loaded only once:
(function (window, undefined) {
History.Adapter.bind(window, 'statechange', function () {
var state = History.getState();
if (state.data.options == undefined) {
alert("options is undefined");
var options = {
url: state.url,
type: "GET",
dataType: "html"
};
GetPartial(options);
} else {
GetPartial(state.data.options);
}
});
})(window);
$(document).on('click', 'a', function (e) {
e.preventDefault();
var options = {
url: $(this).prop('href'),
type: "GET",
dataType: "html"
};
History.pushState({ options: options }, $(this).text(), $(this).prop('href'));
});
function GetPartial(options) {
if (options) {
$.ajax({
url: options.url,
type: options.type || 'GET',
dataType: options.datatype || 'html',
async: true,
data: options.dataToPost,
beforeSend: function() {
$("#loaderMain").show();
},
complete: function() {
$("#loaderMain").hide();
},
cache: false,
}).success(function(response, status, xhr) {
var ct = xhr.getResponseHeader("content-type") || "";
if (ct.indexOf('html') > -1) {
// returned result is of type html, so act accordingly
if (options.selector == undefined) {
InjectContentToShell(response);
} else {
$(options.selector).empty().append(response);
}
} else if (ct.indexOf('json') > -1) {
// returned result is of type json, so act accordingly
}
}).fail(function(e) {
console.log(e);
});
}
}
function InjectContentToShell(content) {
$('#shell').fadeOut(100, function () {
$(this).empty().append(content);
}).fadeIn(100);
}
When I render this first page, I add one entry to History by pushState method like this:
$('#submit').on('click', function (e) {
e.preventDefault();
var formInstance = $(this).closest('form'),
dataToPost = formInstance.serialize();
var options = {
url: formInstance.prop('action'),
type: formInstance.prop('method'),
dataType: "html",
dataToPost: dataToPost
};
History.pushState({ options: options }, "Home - All Summary Views", "/Home/Index");
});
Pushing the state above, changes the url to http://localhost:1089/#Home/Index in html4 browser which is fine. I am able to go back and forward. This works well.
Now when I refresh the page in html4 browsers, the request sent to server is for first url i.e. http://localhost:1089/ which bring the first view to the client. So, the user can see the first page i.e. login screen. And then statechange event is fired and the state url still remembers the last url where page was refreshed and a new request is made for this url to server. The response is then injected in shell.
So, the problem is - on page refresh, user is getting two views instantly - the initial page where the user started his browsing session and soon the second page is loaded from the server and added to shell via animation as when the statechange event is fired, the History.getState() still remembers the last url.
I don't want to show this initial page on page refresh. If this is solved, then everything works fine with this history.js I think!
The above problem is also mentioned as a concept of bookmarking in the this article. Refer to the first figure and the text written above it.
My demo application works fine in html5 browsers as on every History.pushState() the browser's url is changed to the url I have specified. And when page is refreshed, the request is sent to the server as per that url and not with the first url in the browsing session started.
After trying many things, I have come up with the following solution to avoid showing the first view i.e. login page to the users with html4 browser:
I have created a view "Index" that is the first view being rendered. Which doesn't have any html content but has this script:
<script>
$(function () {
if (History.getCurrentIndex() == 0) {
var options = {
url: "/Account/Login",
type: "GET",
dataType: "html"
};
History.pushState({ options: options }, "Login Page", "/Account/Login");
}
});
</script>
The above code checks if the current index is 0 or not. If it is 0, then it means that user has just started his browsing history and it should give a login screen. If it is not 0, then it means that user was on some other step of user journey within the application which does nothing. And once this view is rendered the statechange event is fired which already has the information about the url of the page where user requested for refresh. As per the logic of statechange event handler above in my question, that resource is requested from the server and injected in the #shell container.
The above solution is working very well and gives the same experience to user as if they are on html5 browser. The above code works for me but will be glad to know if someone has any other solution.

Javascript / Ajax Redirect Issues

Very new to code in general so apologies in advance if i dont explain myself properly,
But I have a form, that actions a piece of JavaScript on submit.
If the form validates successfully then it calls a php file for server side processing.
Once the server side processing is complete the php file returns some data (a url) which the user is then redirected to (client side)
This all works fine on desktop (chrome, IE, FF) and via modern mobile devices, however the redirect is not working on some devices (blackberry for one), and a i assume other older devices. Instead of the redirect URL going straight into the address bar, it is being placed after the url of the original page - as such causing the user to be redirected to a page that of course doesnt exist.
Below is the script that is called on submit. Again apologies if none of the above makes sense...I am very new to all this:
$(function () {
$('#wait').hide();
$('form#leads_form').on('submit', function (e) {
if (validateFrm()) {
$(":submit", this).attr("disabled", true);
$('#wait').show();
var jqxhr = $.ajax({
type: 'post',
timeout: 300000,
url: 'sell-save-leads.php',
cache: false,
data: $('form').serialize(),
success: function (data) {
//alert("Submit success: " + data);
window.top.location.href = data;
}
});
} else {
//alert("validation errors");
$('#wait').hide();
}
e.preventDefault();
});
});
If anyone is able to help or offer some advice that would be great.
As your form is located in an iFrame I suggest you to use this jQuery plugin to send messages from an iframe to its parent:
http://benalman.com/projects/jquery-postmessage-plugin/
With this you could send a message from inside your success function, containing the new url, and catch it in the parent window.
You can also use
window.top.location.assign(data);
Ref: https://developer.mozilla.org/en-US/docs/Web/API/Window.location

How can I check for live updates without using setInterval/timeout?

Building a social network, I'm trying to fetch live notifications. Currently, the site sends an AJAX request every few seconds using setInterval. It looks something like this:
setInterval ( function(){
url = base_dir+"/ajax/file.php";
data = "data=someData";
$.ajax({
type: "POST",
url: url,
data: data,
dataType: "json",
beforeSend: function(x) {
if(x && x.overrideMimeType) {
x.overrideMimeType("application/json;charset=UTF-8");
}
},
success: function(JSON){
// retrieve data here
}
});
}, 5000);
That works perfectly, but I'm very worried about that creating servers overload. I tried the comet technique but for some reason it sends much more requests than the above code.
Is there any other more useful technique for pushing this data live?
EDIT:
For implementing long polling I used the following (used the example mentioned here: http://techoctave.com/c7/posts/60-simple-long-polling-example-with-javascript-and-jquery):
(function poll(){
url = base_dir+"/ajax/file.php";
data = "data=someData";
$.ajax({
type: "POST",
url: url,
data: data,
dataType: "json",
beforeSend: function(x) {
if(x && x.overrideMimeType) {
x.overrideMimeType("application/json;charset=UTF-8");
}
},
success: function(JSON){
// retrieve data here
},
complete: poll,
timeout: 5000
});
})();
There's a possibility that I might not get the comet principle right.
PHP code:
// Checks for new notifications, and updates the title and notifications bar if there are any
private static function NotificationsCounter (){
//self::$it_user_id = query that retrieves my id for further checks;
//$friend_requests_count = query that retrieves the friend requests count;
//$updates_count = query that retrieves the updates count;
$total_notifications = $friend_requests_count+$updates_count;
if ($total_notifications > 0) $addToTitle = "(".$total_notifications.")";
else $addToTitle = "";
if ($updates_count > 0) $counterHTML = "<span class='notification_counter' id='updates_counter' style='float: right;'>".$updates_count."</span>";
else $counterHTML = "";
$data = array("counter"=>$total_notifications,"addToTitle"=>$addToTitle,"counterHTML"=>$counterHTML,);
echo json_encode($data); // parse to json and print
}
Since Facebook uses PHP as well, how do they do it?
You should use websockets. You can connect to the server and register onmessage handler. Whenever the server has anything to be send to client, your handler will get invoked. No timeout needed.
Check for websocket support in your browser. As of now, only Chrome, Opera and Safari support them.
if ('WebSocket' in window){
/* WebSocket is supported. You can proceed with your code*/
} else {
/*WebSockets are not supported. Try a fallback method like long-polling etc*/
}
Connecting
var connection = new WebSocket('ws://example.org:12345/myapp');
Handlers
connection.onopen = function(){
console.log('Connection open!');
}
connection.onclose = function(){
console.log('Connection closed');
}
connection.onmessage = function(e){
var server_message = e.data;
console.log(server_message);
}
Documentation: http://www.developerfusion.com/article/143158/an-introduction-to-websockets/
Websockets will be the way to go once they are more universally implemented across the major browsers - I would guess a minimum of 5 years.
The last I heard Facebook chat uses comet and a whole bunch of servers. If you want something more lightweight I can think of two options.
Reduce the polling interval. This is strictly a UI issue - users may have a perfectly acceptable experience with intervals as long as a couple minutes. The only way to know for certain is through user testing, but polling every 5 seconds is probably overkill. No matter what you choose as the optimal interval, this does give you an quick way to scale if you are getting hammered - just crank up the interval until the servers stop melting.
Use HTTP validation caching. You can make the requests more lightweight if the server only returns a response body when the content has changed since the last request. You will have to build something custom using ETag or Last-Modified headers and a lightweight modification checking system on the server, but it might save you a few bytes.

iPhone Web Application: Window.location doesn't seem to work

I have added the required meta tags to my web app so that it can be launched on an iPhone from the springboard with no safari elements (address bar etc).
However, my login page works via JS, with the response coming back as JSON.
In Safari, when not launched as a web app, the redirect works fine (using window.location).
When launched as a web app, the redirect doesn't seem to work properly. The screen will refresh but be on the same page.
Is this a limitation of a web app or (as I suspect) am I doing it wrong?
This is the code that responds to the ajax post
genericPost: function (f, ajaxLoad) {
if (ajaxLoad == undefined)
ajaxLoad = true;
var form = $(f);
var data = form.serialize();
var action = form.attr("action");
$.ajax({
type: 'POST',
url: action,
data: data,
success: function (response) {
if (response.worked) {
//navigate to the next required page
//Notify.showMessage(response.message);
if (response.redirect) {
if (ajaxLoad) {
Notify.showMessage(response.message, "ok");
var back = response.direction == "back";
$.mobile.changePage(response.redirect, "slide", back, true);
}
else {
window.location = response.redirect;
}
}
else {
Notify.showMessage(response.message, "ok");
}
}
else {
Notify.showMessage(response.message, "error");
}
},
dataType: "json",
error: function () {
Notify.showMessage("Could not submit your form at the time. Please try again. Please try again", "error");
}
});
}
Thanks
Ok, so the window.location was a red herring.
The issue was that ios seems to send a different user agent string when running full screen, one that IIS did not like.
IIS therefore decided that this browser did not support cookies or any of that stuff so the authentication token was failing.
This was fixed by adding a app_devices folder to my project and a .browser file.

Categories