I'm doing a Exam on a Web page works descending in advance so that if the time is up in question closes the question was the piece successfully through the following function
<script>
function countdown() {
> window.location.href="#Url.Action("TimeOver", "Answers"} )";
> }
setTimeout(function () { countdown(); }, 1000);
</script>
The bad thing is that when you refresh the page again restores the interim as if time did not end Can I bypass it, or is it inevitable fate
Short answer - no unless your users are authenticated.
If they are authenticated then you need to persist the timestamp that they first requested the question in your database. Disable browser caching and check for an existing timestamp on page load and check it against the time the answer is submitted. Anything done client side is not reliable, although usually delivers a better UX.
You could implement it using cookies and javascript if it's not mission critical, although this is easily bypassed by a power user, let alone a skilled attacker.
Related
It would appear that the savechanges method on breeze waits indefinitely when calling to or waiting for the server. Is there a way of getting it to time out? I am calling save change with allowConcurrentSaves: false. This now causes users who somehow do not get a response from the server to simply hang in limbo indefinitely say for example with a dropped internet connection.
I do not want to re-call the method with allowConcurrentSaves to false fearing that I might duplicate the data.
Any ideas?
Thanks
Update 16 May 2014
You can set HTTP-level timeout and cancellation with the AJAX Adapter's requestInterceptor as of v.1.4.12. See the documentation, "Controlling AJAX calls".
I'd still be reluctant to use this feature on save as you have no chance of knowing what whether the server persisted the data or not. Of course if your client hangs or crashes you don't know anyway. It's up to you.
Original Answer
Actually, there is a ready-made solution from Q.js. It's called timeout and it's mentioned in the API reference with a simplified example of its implementation and use in the readme.md.
I know you asked about Save but your question is pertinent for promises in general. Here is a query example adapted from the queryTests.js in our DocCode Sample
var timeoutMs = 10000; // 10 second timeout
var em = newEm(); // creates a new EntityManager
var query = new EntityQuery().from("Customers").using(em);
Q.timeout(query.execute, timeoutMs)
.then(queryFinishedBeforeTimeout)
.fail(queryFailedOrTimedout);
function queryFailedOrTimedout(error) {
var expect = /timed out/i;
var emsg = error.message;
if (expect.test(emsg)) {
log("Query timed out w/ message '{0}' " + expectTimeoutMsg)
.format(emsg));
// do something
} else {
handleFail(error);
}
}
Note: I just added this test so you'd have to get if from github or wait for a Breeze release after 1.2.5.
Oops ... maybe not
I gave what I think is a great answer for query. It may not be the right answer for save.
The problem with save is that you do not know on the client if the save succeeded until the server responds. Things could go wrong anywhere along the way. The server might not have heard the request to save. The server may have failed during save. The server may have saved the data but the response never made it back to the client.
Changing the value of allowConcurrentSaves won't get you out of this bind. Neither will having a save timeout.
In fact, adding a timeout to the save is probably deceiving. It is even possible for the save response to arrive after your custom timeout ... in which case Breeze will have tried to update your EntityManager ... and you won't know if Breeze succeeded or failed!
What if we added a Breeze save timeout. What should it do? What if breeze said the save had timedout ... and Breeze ignored a belated response from the server? Then imagine that the save succeeded on the server - it just took "too long" for it to respond to the client. Now you've got a client whose state is unexpectedly out of sync with the server. This is not good.
So I think you want a different solution to this very real problem. It's a user experience problem really. You can indicate to the user that you think the save is still in progress and then set your own timer. If the save isn't done when your timer expires, you can query the server to see if the data have been saved or if there is a connection ... or something along these lines. I can't think of a better way right now honestly.
Note that I'm assuming you need to know that the server succeeded. If you avoid store-generated IDs and always assume saves succeed unless the server tells you otherwise ... well that's a completely different paradigm and programming model that we could talk about someday (see meteorjs).
The net of all of this: I'm pretty darned sure that a save timeout is NOT what you want.
Still useful on a query though :)
Great question, and I wish I had a good answer. But it is definitely worth looking into. Could you please add this as a feature request to the Breeze User Voice. We take these requests very seriously in determining our priorities for Breeze development.
What are the preferred ways to do a redirection and a reload in Dart?
Do we just use: window.location.href = window.location.href?
There are a few different ways to handle URI changes and each have their own purpose.
When you want to send the user to another URI:
window.location.assign('http://google.com')
This one sends the user to Google, keeping the browsing history (the back button history). This is like clicking on a link.
window.location.href = 'http://google.com'
The same as above, just another way to do it. href is a setter, and causes the assignment to happen. I feel the previous version is cleaner.
window.location.replace('http://google.com');
However, the replace() method on LocalLocation object does not only send the user to Google, but also does not put the originating page in the session history, which means the user will not suffer from the never-ending back-button nightmare.
This is essentially the same as an HTTP redirect. The history is skipped.
When you want to do a reload/refresh.
window.location.assign(window.location.href)
Reloads the current page to the exact same URI. This does not contain POST data. Some of the resources (like images, etc.) may me reloaded from the cache, so it might not be a full reload.
This is essentially the same as pressing F5 and skipping the sending of POST data.
window.location.href = window.location.href
Again, the same as previous.
window.location.reload()
This way of reloading the page causes also the POST data to be sent. The "JavaScript version" of window.location.reload() also supports a parameter that specifies whether to skip the cache or not. However, the current Dart implementation does not support that parameter, and defaults to fetch the resources from cache.
This cache parameter may be added to Dart at some point, but it's not there yet. When it arrives, you most likely just pass true as the first parameter and then it would be like Ctrl + Shift + R.
Summary
I want to simulate a click on <a> tag.
Use window.location.assign(url).
I want to redirect to a new website like the HTTP redirection and skip the back-button history.
Use window.location.replace(url).
I want to do an F5 with POST data.
Use window.location.reload().
I want to do an F5 without POST data.
Use window.location.assign(window.location.href).
I want to do an Ctrl + Shift + F5.
Not available, maybe in the future. It would probably be window.location.reload(true).
In this railscast our good friend Mr. Bates walks through a solution to creating an app that can search, sort, and paginate a set of data. When going through AJAX searching he provides a solution that will display results of the search the moment a user enters input into the search box. Here is his solution:
$('#products_search input').keyup(function () {
$.get($('#products_search').attr('action'), ↵
$('#products_search').serialize(), null, 'script');
return false;
});
However he states "Note that this is only a quick demo and isn’t the best way to do this. There are several jQuery plugins that you can use if you do something like this in a production app." I'm looking for an explanation on why he believes this isn't suitable for production. Thanks in advance!
There are two major issues I see with this solution. The first is that you are making an HTTP (AJAX) request every time a key is pressed, which will not be the most efficient way of doing this. The second is that you are basically calling eval in the response, and eval is bad as it can lead to malicious users executing code you don't want to be executed.
Some suggestions on improving:
Use a proper JSON parser and pass the data back as JSON. (you can use $.getJSON)
Throttle the request - don't do it on every keyUp, maybe start a timer and only submit the request if no keys have been pressed in the last second, meaning it won't make lots of calls for people who type fast.
Cache the response. If you have already searched for something, then there is no point fetching the data twice. Keep a note (in a JS Object) of previous calls in this session and their results.
What would be the best approach for a Play! application to remember the user? I think the only possible solution is to use the client side cookies, right? But as soon as the browser shuts down, this session is destroyed and not valid for the next request? How did/do you solve(d) this?
As for now, I ser the crypted userid in the session (per session), like this:
session("userid", user.id);
And then I use the interceptor to avoid passing parameters every when I need them oft, like described here: How to avoid passing parameters everywhere in play2?
But how to remember the user, or even beter, automatically log the user in on the next request?
EDIT: 2016-03-11
Be aware that some browser may store the session cookie for a longer period. For instance you can set in Chrome to remember the open tabs on next visit. This means that the Play Session cookie will be restored next time you open the browser.
And as of Play 2.4 the session cookie maxAge (you need to set in the application.conf) is renamed to: play.http.session.maxAge
To make the session not time-out when a users closes their browser you can use the session.maxAge parameter in the application.conf.
e.g.:
# Set session maximum age in seconds (4w)
session.maxAge=2419200
Quoting from Play 2.0 Session Documentation:
There is no technical timeout for the Session. It expires when the user closes the web browser. If you need a functional timeout for a specific application, just store a timestamp into the user Session and use it however your application needs (e.g. for a maximum session duration, maxmimum inactivity duration, etc.).
For security reasons, modern browsers will invalidate cookies on exit, and this is not something you can change simply because it would allow hackers to bad things with credentials that they do not rightfully have.
I would reevalutate whether or not you truly want the user to stay logged in, since it is usually a security risk to do so. If, however, you decide that you still want the user to stay logged in, you will have to try something that is not cookie based, and at the moment, I'm not sure what that would look like.
If you don't force a newSession or the user doesn't remove the cookies, the user should still be logged in.
It may be that your browser is set up to remove cookies when closing, or you are suffering from an external sideeffect. But I can confirm that cookies persist in my dev environment (in both Chrome and Firefox) after closing the browser.
I tried this and it worked for me. It's basically a composed Action.
def RememberAction(f: Request[AnyContent] => Result): Action[AnyContent] = {
Action { request =>
if(!request.session.get("email").isDefined && request.cookies.get("remember-email").isDefined) {
f(request).asInstanceOf[PlainResult].withSession("email" -> request.cookies.get("remember-email").get.value)
} else {
f(request)
}
}
}
Then you can use this Action in your controllers like this:
def index = RememberAction { implicit request =>
Ok("Hello World!")
}
I have set up Facebook Connect on my site, and the login is working fine. I have set up a listener to detect a login state change, as follows:
FB.Event.subscribe('auth.sessionChange', function() {
window.location.reload();
});
All good. Except that leaving a browser window open causes the page to reload after perhaps 20mins. So the auth.sessionChange is firing at some interval. Which can caused havoc, particularly if the last page was a POST form submission.
In the FB docs it says "Sessions are refreshed over time as long as the user is active with your app." How often is this session refreshed?
And how can I protect the page from reloading if it doesn't need to? A conditional maybe within that function??
EDIT - adding information for clarification:
I thought I would add some info to give those offering the advice some more to go on (thanks so far BTW):
the reason I have the listener triggering a reload is because I wanted users to be logged in to the site every time they visit - if they already had a session in FB. I was detecting an active session with the JS SDK, which I know could do log in on its own, but I needed to trigger a page reload after the JS had done the detection, in order to set a PHP session for the site - required step. I couldn't do the PHP login without first letting the JS detect the FB session in the browser.
Usually you can see the length of the validity of the session just by looking at the session itself. However in many cases, I suggest requesting the offline_access permission to ensure the access_token remains valid as long as the user doesn't change their password and doesn't remove your application.
Andy, if you are only listening for login state then subscribe to auth.login and auth.logout instead of auth.sessionChange.
If you need an active session for a user to take an action on your site, use FB.getLoginStatus() or FB.getSession() to check the session object.
http://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/
http://developers.facebook.com/docs/reference/javascript/FB.getSession/
It really depends on your App work-flow and the below is just a general approach.
You can have a flag that presents in all your pages (maybe in your main layout if you are using a template system) with a setter function to be executed once you don't need a page reload to happen. Something like:
var do_reload = true; // By default, we always allow a reload
FB.Event.subscribe('auth.sessionChange', function() {
if( do_reload ) {
window.location.reload();
}
});
// Call this whenever you don't want 'auth.sessionChange' to reload the page
function turnoff_reload() {
do_reload = false;
}
// Call this to return to default behavior
function turnon_reload() {
do_reload = true;
}
Now if you are "redirecting" the user (e.g.: after a form post) to a page that doesn't require a reload then you need to set the flag in the first line to false.
Another scenario if you have an ajax loaded content based on the user interaction, if the page reloads by itself that content will be lost and the user needs to interact again to view that content, what can be done here is setting the flag to false after the Ajax call.