Prevent from route change in AngularJS - ajax

$rootScope.$on("$locationChangeStart", function(event, next, current) {
var partsOfUrl = next.split('/');
var isLogin = false;
if(partsOfUrl.indexOf("signin") > 0) {
isLogin = true;
}
var myDataPromise = loginService.getData();
myDataPromise.then(function(data) { // this is only run after $http completes
if(!isLogin) {
if(data.logout) {
$location.url("pages/signin");
event.preventDefault();
} else{}
} else {
if(data.logout) {
} else {
}
}
});
console.log(next);
});
This is the code i used to check user authentication and prevent the protected areas. But problem here is if a user try to access protected then immediately browser shows the secure page and then get back to login page instead of redirecting to login page first. I think that's because of user authentication process is done through an Ajax call so the program never holds for the response. What's the wrong here and how should i get rid of it ?

Try with httpInterceptor (from mean.io stack)
btw the server should response with a 401 status
'use strict';
angular.module('mean-factory-interceptor',[])
.factory('httpInterceptor', ['$q','$location',function ($q,$location) {
return {
'response': function(response) {
if (response.status === 401) {
$location.path('/signin');
return $q.reject(response);
}
return response || $q.when(response);
},
'responseError': function(rejection) {
if (rejection.status === 401) {
$location.url('/signin');
return $q.reject(rejection);
}
return $q.reject(rejection);
}
};
}
])
//Http Intercpetor to check auth failures for xhr requests
.config(['$httpProvider',function($httpProvider) {
$httpProvider.interceptors.push('httpInterceptor');
}]);

Related

How can I send a synchronous ajax request to my server in onunload function

I need to send a ajax request to my server before web page close, my send code is below.
SendByAajx = function(msg) {
var response;
var xmlHttpReg;
if(window.XMLHttpRequest){
xmlHttpReg = new XMLHttpRequest();
} else if(window.ActiveXObject) {
xmlHttpReg = new ActiveXObject("Microsoft.XMLHTTP");
} else {
throw new Error("Unsupported borwser");
}
if(xmlHttpReg != null) {
xmlHttpReg.open("get", "https://127.0.0.1:57688/test"+'?'+msg, false);
xmlHttpReg.send(null);
if(xmlHttpReg.readyState==4){
if(xmlHttpReg.status == 200) {
var data = JSON.parse(xmlHttpReg.responseText);
if(typeof(data.errorcode) == "number" &&
data.errorcode != 0) {
throw("response error:" + data.errorcode);
}
response = data.result;
} else {
throw new Error("Error");
}
}
}
return response;
}
When I call this function in a button onclick event, it works.
function GetOnClick() {
try{
var result = SendByAajx (“data”);
} catch (e) {
//alert(errorInfo);
}
SetButtonDisabled(false);
}
But when I call this function when the page is unloaded, it doesn't work.
<body onload="javascript:OnLoad();" onunload="javascript:OnUnLoad()">
function OnUnLoad() {
try{
var result = SendByAajx(“data”);
} catch (e) {
//alert(errorInfo);
}
}
When I debug the application, the JS execution stops after this line:
xmlHttpReg.send(null);
It didn’t go to the next line:
if(xmlHttpReg.readyState==4)
The “data” is also not sent to the server.
What is wrong with my program, can ajax be called in an onunload function? What should I do to make it work?

Using a URL query parameter to version cached responses

I am trying to cache specific urls and each url has md5 hash and If the urls updated with new md5 i want to remove the current cache and add the new one.
cached url: http://www.mysite.lo/cards/index.php?md5=f51c2ef7795480ef2e0b1bd24c9e07
function shouldFetch(event) {
if ( event.request.url.indexOf( '/cards/') == -1 ) {
return false;
}
return true;
}
self.addEventListener('fetch', function(event) {
if (shouldFetch(event)) {
event.respondWith(
caches.match(event.request).then(function(response) {
if (response !== undefined) {
return response;
} else {
return fetch(event.request).then(function (response) {
let responseClone = response.clone();
caches.open('v1').then(function (cache) {
cache.put(event.request, responseClone);
});
return response;
}).catch(function (err) {
return caches.match(event.request);
});
}
})
);
}
});
I know we can use caches.delete() and so on, but I want to call it only if the md5 updated from the new request.
Thanks
You can accomplish roughly what you describe with the following, which makes use of the ignoreSearch option when calling cache.matchAll():
self.addEventListener('fetch', (event) => {
const CACHE_NAME = '...';
const url = new URL(event.request.url);
if (url.searchParams.has('md5')) {
event.respondWith((async () => {
const cache = await caches.open(CACHE_NAME);
const cachedResponses = await cache.matchAll(url.href, {
// https://developers.google.com/web/updates/2016/09/cache-query-options
ignoreSearch: true,
});
for (const cachedResponse of cachedResponses) {
// If we already have the incoming URL cached, return it.
if (cachedResponse.url === url.href) {
return cachedResponse;
}
// Otherwise, delete the out of date response.
await cache.delete(cachedResponse.url);
}
// If we've gotten this far, then there wasn't a cache match,
// and our old entries have been cleaned up.
const response = await fetch(event.request);
await cache.put(event.request, response.clone());
return response;
})());
}
// Logic for non-md5 use cases goes here.
});
(You could make things slightly more efficient by rearranging some of the cache-manipulation code to bring it out of the critical response path, but that's the basic idea.)

How make nested http query in AngularJs?

Iam build single page app in AngularJs,and I need call Facebook UI dialog.And if user click 'ok',or 'cancel',successReport methos not call immediately.This method call after i click on any button in page,or link.Similar to internal queue
service.showStreamDialog=function (json) {
if (json.stream) {
var newCardSentId = json.cardSentId;
FB.ui(json.stream, function (resp) {
if (resp && resp.post_id) {
reportService.successReport(newCardSentId,newCardSentId,resp.post_id);
} else {
reportService.cancelReport(newCardSentId);
}
});
}
};
// in other file
var successReport=function(cardId,cardSentId,postId){
var defered = $q.defer();
$http.post(reportUrl,$.param({
cardId:cardId,
cardSentId:cardSentId,
postId:postId,
accessToken: ACCESS_TOKEN
}))
.success(function(data){
defered.resolve(data);})
.error(function(data){
defered.reject(data);
});
return defered.promise;
};
I found problem. It was in integration facebook api in my app.I add $rootScope.$apply call,
and all working as i expected
service.showStreamDialog = function (json) {
if (json.stream) {
var newCardSentId = json.cardSentId;
FB.ui(json.stream, function (resp) {
if (resp && resp.post_id) {
$rootScope.$apply(function () {
$rootScope.$broadcast('CARD_SENT_SUCCESS', {cardSentId: newCardSentId,post_id:resp.post_id});
});
} else {
$rootScope.$apply(function () {
$rootScope.$broadcast('CARD_SENT_CANCEL', {cardSentId: newCardSentId});
});
}
});
}
};

Facebook App/Page Tab with xmlHttpRequest doesn't work in Firefox

I have e really big problem with firefox and facebook.
I mad an application on my webserver which uses xmlHttpRequest. I added this application to a facebook tab on a test facebook page. It works with IE, Chrome, Safari but not with firefox.
The request just keeps loading until timeout.
The JS functions i'm using:
function createXmlHttpRequest() {
try {
if (typeof ActiveXObject != 'undefined') {
return new ActiveXObject('Microsoft.XMLHTTP');
} else if (window["XMLHttpRequest"]) {
return new XMLHttpRequest();
}
} catch (e) {
changeStatus(e);
}
return null;
};
function downloadUrl(url, callback) {
var status = -1;
var request = createXmlHttpRequest();
if (!request) {
return false;
}
request.onreadystatechange = function() {
if (request.readyState == 4) {
try {
status = request.status;
} catch (e) {
}
if (status == 200) {
callback(request.responseXML, request.status);
request.onreadystatechange = function() {};
}
}
}
request.open('GET', url, f);
try {
request.send(null);
} catch (e) {
changeStatus(e);
}
};
function xmlParse(str) {
if (typeof ActiveXObject != 'undefined' && typeof GetObject != 'undefined') {
var doc = new ActiveXObject('Microsoft.XMLDOM');
doc.loadXML(str);
return doc;
}
if (typeof DOMParser != 'undefined') {
return (new DOMParser()).parseFromString(str, 'text/xml');
}
return createElement('div', null);
}
function downloadScript(url) {
var script = document.createElement('script');
script.src = url;
document.body.appendChild(script);
}
i call it through downloadUrl()
The Headers from the requested files:
header('Access-Control: allow <*>');
header("Access-Control-Allow-Origin: *");
header('Access-Control-Allow-Methods: GET');
header('Access-Control-Allow-Headers: X-PINGOTHER');
header("Content-type: text/xml");
i really tried everything, but it won't work in firefox...
what i've noticed: by observing firebug while loading this app in the facebook tab i could see that facebook is not requesting the adress given in the source, but other ones like: https://0-317.channel.facebook.com/pull?channel=p_1495135952&seq=389&partition=7&clientid=420773d2&cb=682&idle=0&state=active
i think it's surely firefox cross domain policy... but how can i solve this problem?
Anyone had the same problems ?
I thank you in advance.
Greetings
ok, found the problem.
Facebook is using UTF-8, but my page wasn't. So the stopped at the umlauts.
So it wasn't the Request at all.

AJAX - Return responseText

I've seen the myriad threads sprawled across the Internet about the following similar code in an AJAX request returning undefined:
AJAX.onreadystatechange = function() {
if(AJAX.readyState == 4) {
if(AJAX.status == 200) {
var response = AJAX.responseText;
return response;
}
else {
window.alert('Error: ' + AJAX.status);
return false;
}
}
};
I know that I'm supposed to "do something with" responseText like writing it to the HTML. The problem: I don't have that luxury. This bit of code is intended to be inside of a generic method for running fast AJAX requests that way all the code for making an AJAX request doesn't have to written out over and over again (~40×) with the chance of a minor problem here or there that breaks the application.
My method HAS to explicitly return responseText "or else." No writing to HTML. How would I do this? Also, I'd appreciate a lack of plugs for JQuery.
What I'm looking for:
function doAjax(param) {
// set up XmlHttpRequest
AJAX.onreadystatechange = function() {
if(AJAX.readyState == 4) {
if(AJAX.status == 200) {
var response = AJAX.responseText;
return response;
}
else {
window.alert('Error: ' + AJAX.status);
return false;
}
}
};
// send data
}
...
function doSpecificAjax() {
var param = array();
var result = doAjax(param);
// manipulate result
}
Doing a little research I came across this SOF post:
Ajax responseText comes back as undefined
Based on that post, it looks like you may want to implement your ajax method like this:
function doRequest(url, callback) {
var xmlhttp = ....; // create a new request here
xmlhttp.open("GET", url, true); // for async
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4) {
if (xmlhttp.status == 200) {
// pass the response to the callback function
callback(null, xmlhttp.responseText);
} else {
// pass the error to the callback function
callback(xmlhttp.statusText);
}
}
}
xmlhttp.send(null);
}
Then, you can call that method like this...
doRequest('http://mysite.com/foo', function(err, response) { // pass an anonymous function
if (err) {
return "";
} else {
return response;
}
});
This should return the responseText accurately. Let me know if this doesn't give you back the correct results.

Resources