Handle fetch in service worker but allow client to see redirect - service-worker

I have a url, /users/sign_out, that is supposed log out a user and redirect them to my root url, /. I want to handle this fetch through my service worker, because I want to clean some items out of the cache before sending the user back to root. However, since the client doesn't see the redirect that happens on the fetch from the service worker, the user winds up on my splash screen but sees the pre-redirect address /users/sign_out.
Is there any way currently that I can handle the fetch and also allow the client to see the correct final url?
It appears that eventually there will be a Response.redirect() method that will allow updating a response with the final url. It looks like there is also likely to be some kind of finalURL option that would also address this case. But is there anything that I can use now? On Twitter, Jake Archibald (#jaffathecake) said I could construct a new Response myself - and I can, but even after looking at the spec and the MDN docs a bit, I still can't figure out how to specify the correct url for it.
If there is in fact a way to construct a Response object that does what I need, could someone show me how that works?

There's an example at https://github.com/GoogleChrome/samples/tree/gh-pages/service-worker/mock-responses showing how you could create a Response object and use it to respond to a fetch event.
In that case, we're creating a 200 OK response with a body, but there's nothing stopping you from creating an arbitrary response. You'd probably want a 302 Found for your use case, so you'd do something like:
var responseInit = {
status: 302,
statusText: 'Found',
headers: {
Location: '/' // Or whatever URL you want to redirect to.
}
};
var redirectResponse = new Response('', responseInit);
event.respondWith(redirectResponse);
You can include code that clears your caches inside the fetch handler before you respond to the event, and you'd obviously want to check the event.request.url value first to make sure you only respond to requests for /users/sign_out with your custom response.

Related

How to retrieve final URL in Postman test with Redirect turned on

I wish to test the URL at the end of a series of redirects. With Automatically follow redirects on, this appears not to be possible.
I have a number of redirects when my Postman request is made and I would like them to be executed automatically, so I am not turning off Automatically follow redirects, but my test needs to check the final URL of the request:
pm.test("URL contains final addr", function () {
pm.expect(pm.response.url).to.include("/Customer.aspx");
});
This question is very similar to this post however I need to still get the URL with redirection turned on.
How should I be retrieving the true, final URL after a number of redirects?

How can I redirect to a particular view based on url in grails

I am using grails 2.5.5 version, Suppose I am entering url as www.localhost:8080/app-name then it should open the MyHome.gsp, suppose if I give other url ex: demo1.localhost.com:8080/app-name then it should redirect to some login page like login.jsp. How can I do that?
Let me break it up for you :
Suppose I have www.localhost:8080/app-name
suppose if I give other url ex: demo1.localhost.com:8080/app-name
Your app starts here:
Case 1 :/app-name
case 2 :/app-name
The rest of that url is actually DNS and configurating binding tomcat specific or wild card urls to a given application.
So in short you need to filter entire url in the application parse url and redirect in your app accordingly.
You need to then intercept every url with grails 2 there is SecurityFilters which so far as i know works with apache-shiro may also work with spring security.
and within it you need to overall check for something like
URL url = new URL(request.getRequestURL().toString())
String subdomain=url.host
if (subdomain.contains('.')) {
subdomain= subdomain.split('.')[0]
}
that then returns your `demo1` you then redirect it another url if it matches your specific rule.
But as I said you are talking about superficial stuff here as I expressed what the address is or how somone gets to the app has nothing to do with the actual application. This is why IT is big business. Big business not because everyone tries to narrow everything down into one box doing all of this but because when situations likes this happen bigger thinking is needed i.e. do i need a load balancer something like F5 that will split traffic according to a given url and send to another app container that asks for authorisation.
subdomain= subdomain.split('.')[1] in that case then but this leaves room for errors since user could put in demo1.somedomain.com and if that resolves well it is either split by subdomain= subdomain.split('.')[0]
I would do this then
String subdomain=url.host
if (subdomain.contains('.')) {
def splitter= subdomain.split('.')
subdomain= splitter[0]
if (subdomain=='www' && splitter.size()>1) {
subdomain= splitter[1]
}
}

How to handle URLs that aren't controlled by a service worker

My strategy for service worker is if the url matches some particular format then only service worker should intercept it ,otherwise browser should handle it as it does normally ,
for all cases i am using evt.respondWith(), to intercept it and serve a custom response , but what should i do if the url does not match any of the format
I have couple of option and all of them works , but i am not sure which one is logically correct
1)do nothing , means i am having if conditions for checking each of the defined format inside the fetch method but if they do not match i do nothing , i dont have any "else" condition.In this case browser is fetching the page normally , but i am not sure if it is correct , what is actually happening , is cookies getting passed ?
2)inside the else method i have fetch(event.request, { credentials: 'include' });
this also works , i am not sure if i need to include the credential clause here , as per my understanding not service worker but browser is handling the request here , so it will automatically include the cookies . Please correct me if i am wrong here .
3)event.respondWith(fetch(event.request, { credentials: 'include' }));
This also works, i think since i am using event.respondWith, here i need to include the credential explicitly(again i am not sure).But my doubt is do i need to use event.respondWith here. What i know about event.respondWithis that, we use this only if we want to serve a custom response for a fetch event .As we want these requests to be handled as it is , do we need to use event.respondWith here ?
All of my confusions are coming from my lack of knowledge about event.respondWith(), could somebody please explain , exactly when should i use
it ?
event.respondWith allows you to respond to a network request with a response that you create (either by using fetch, or the Cache API, or even created manually with the Response constructor).
If you don't call it in the fetch event handler, the browser will handle the request.
If you call it with fetch(event.request), it's basically the same as letting the browser handle it (because fetch is going to perform exactly the same request the browser would have performed if you hadn't called event.respondWith).
Note that event.respondWith will respond with the value you pass to it or with the value that the promise you pass to it is resolved to.
event.respondWith(new Response('Some body.'));
event.respondWith(new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(new Response('Some body.'));
}, 1000);
}));

MVC URL: show 1 parameter & hide second

Suppose I have URL as
http://someurl.com/Search?q=a&page=8
(Above mentioned URL is getting called throug AJAX, in MVC4.paging)
What I want is to show only upto http://someurl.com/Search?q=a
I want to hide my second parameter which is page=8
Is this possible?
EDIT: More confusion to add.
<a data-ajax="true" data-ajax-loading="#divLoading" data-ajax-method="POST" data-ajax-mode="replace" data-ajax-success="successPaging" data-ajax-update="#searchresults" href="/Search?q=a&page=1" title="Go to first page"><<</a>
Is button of Next in my Paging, it is making an AJAX request, So I don't know how to change GET to POST for this.
The URL isn't there just for looks; it's telling the server what resource is being requested, and in the case of a query string, that's information the server needs to return a response. http://someurl.com/Search?q=a is a completely different resource than http://someurl.com/Search?q=a&page=8. With a GET request, all you have is the URL, so all the information the server needs must be in the URL. What others in the comments are telling you to do is use a POST request, which among other things includes a post body. In other words, you can pass information to the server both in the URL and in the post body. That allows you to remove the page parameter from the URL and include it in the post body instead. That's the only way you can achieve what you want.
That said, strictly speaking, a POST is inappropriate for fetching a resource like this. POST should be used to update or modify a resource or to call some atomic method in an API scenario. It can also be used for the creation of resources, although PUT is more appropriate there. GET is supposed to be used to return a resource which is not variable. For example, any request to http://someurl.com/Search?q=a&page=8 should always return the same response no matter what client requests it. And, it's even less important what URL is actually being used because the user does not see it at all, since you're requesting it via AJAX (it won't show in the navigation bar). Just keep it as a GET request and leave the parameters as they are.

Where to put Bit.ly API call in Rails app

I'm planning on using Bit.ly Pro and the Bit.ly API to make my own short urls in a Rails 3 project.
I've got a User and a Note model. And a url structure like this: '/username/1-note-title'.
Now I would like to give each note a short url. But I don't know from where I should do the API call. Right now I got this code in the Note controller but I don't know if that's the right place or how to get the url of the specific note...
url = ???
parsed_json = JSON('http://api.bit.ly/v3/shorten?login=bitlyapidemo&apiKey=R_0da49e0a9118ff35f52f629d2d71bf07&longUrl=' + url + '&format=json')
#short_url = parsed_json["data"]["url"]
The JSON object structure just for reference:
{
"status_code": 200,
"data": {
"url": "http://bit.ly/cmeH01",
"hash": "cmeH01",
"global_hash": "1YKMfY",
"long_url": "http://betaworks.com/",
"new_hash": 0
},
"status_txt": "OK"
}
Help wanted, thanks in advance!
I seems that the short url should get created when a new note is created for a given user. In that context it would happen as the result of a create action in the NotesController (typically). Best practice would suggest that the logical responsibility should live the Note model so I would suggest you do the bit.ly shortening implemented in a save callback, either before or after, depending on how critical it is (in the context of your particular app) for a shortened URL to exist.
The challenge is do deal with the error case which is when the bit.ly service is unable to respond to your shortening request at all or is taking too long in so doing. That's when putting it in the callback may not make sense as it could potentially tie up your application when trying to fulfill the request.
If you don't need live URL shortening then you could consider creating shortening requests as queued jobs in a background process to be done asynchronously (retrying as necessary) and be triggered in the aforementioned after_save callback in your Note model

Resources