More fun and games in my ongoing exploration of the world of JavaScript.
At the moment I am playing with AJAX, and found myself wondering how one would deal with calls from clients whose users were not logged in.
After a bit of experimenting I have found that if you do a plain redirect from the server, the browser happily follows it, but stuffs the result into the response passed to your beautiful AJAX code. So the user is left on the page that ran your AJAX, blissfully unaware of what is going on under the hood. This seems fair: the browser is leaving the decision making up to your AJAX code.
The problem being that if you write a nice filter to redirect all attempts to access protected content to a log in page, and your AJAX code is expecting a nice piece of JSON, there will be tears.
For my naked servlet experiment I have been forced to a slightly hacky solution: I have a created a servlet filter for JSON requests. If it finds that you are not logged in then it wraps the URL of the log in page in a piece of JSON and returns that. If the AJAX handler in the browser finds the redirectTo key in the returned object it promptly redirects the browser to the associated URL and does nothing more.
It would have been nice to handle the whole thing by popping up a log in dialogue (via an iFrame?) and not redirect the user to another page: but I am using Google App Engine as my servlet provider, and it would seem that the terms of service require me not to do this.
This doesn't seem very elegant. I am scratching my head to see if I can come up with a better way, but for the life of me, I can't see it. All hints and tips gratefully accepted!
Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts
Monday, May 23, 2011
JavaScript notes: AJAX and redirects
Labels:
AJAX,
Applet,
JavaScript,
Naked Servlets,
Servlet
Wednesday, April 13, 2011
The naked server
Twitter have abandoned Rails for some parts of their application. I didn't find their description of the move to be fully informative. E.g.: just what do they mean when they say "we launched a replacement for our Ruby-on-Rails front-end"?
Predictably the move got a few comments on the Ruby/Rails newsgroup that I subscribe to. The general consensus seemed to be "so what"?
I think we might all be missing the bigger picture. Perhaps this is just a logical step in the progression of web applications? If so, what does it mean for their future?
To explain my thoughts, some history:
- Way back when, pages viewed in a browser were fairly simple, being mostly static files that were dished up from directories by a dedicated server application.
- Then we needed to make those static pages more dynamic, and to reflect knowledge related to the identity of the person who was viewing those pages. However, browsers were geared to rendering static pages, so we controlled what we could and put the smarts on the server, building frameworks that allowed us to customize each individual page for the viewer. Our first efforts at these frameworks were quite awful, IMHO, but as time went by we got better at it.
- Now web browsers have an common embedded scripting language (ECMAScript): and can create and change whole pages, dynamically, on the fly.
- JavaScript/HTML/CSS is going to grow dramatically in importance (and that seems to be happening).
- node.js is going to become popular. Because if you know JavaScript, and you simply want to fetch some data from the server, or write some back, why not use the same language and, possibly, files, on both sides of the tubes?
Labels:
JavaScript,
Naked Server,
Naked Servlets,
node.js
Thursday, March 31, 2011
JavaScript notes: an Applet puzzle
This one has driven me a little crazy over the last few hours.
As part of my learning about JavaScript and HTML5 I thought I would try embedding an applet in an HTML5 page. Which I could easily do. Then I made the applet record a sound and then replay it. To do this the applet needs to be signed. So no problem, I used a self signed certificate, loaded my applet and everything just worked. Sweet.
The next thing I then tried to do was to get the JavaScript on the web page to call into the applet.
Hacky - In my defense, I was just trying to see if I could get the call to work...
When I pressed the HTML button in my browser:
POW!: java.security.AccessControlException: access denied (javax.sound.sampled.AudioPermission record)
This was a little unexpected - if the applet button was pressed, I recorded. If the HTML button was pressed, then I got a security error.
I Googled the world and found Bug 4406607 and Mozilla bug 60120
But somehow the answers within didn't seem satisfactory.
Then my searches hit gold: Java Access Control Mechanisms (pdf)
A very nice explanation of what was happening, with a simple answer: change my Java method that was being called by the JavaScript to the following:
Now my applet records when I hit the HTML button. Sweet.
As part of my learning about JavaScript and HTML5 I thought I would try embedding an applet in an HTML5 page. Which I could easily do. Then I made the applet record a sound and then replay it. To do this the applet needs to be signed. So no problem, I used a self signed certificate, loaded my applet and everything just worked. Sweet.
The next thing I then tried to do was to get the JavaScript on the web page to call into the applet.
<form>
<input type="button" value="record" onClick="document.getElementById('recorderApplet').doRecord();">
</form>
Hacky - In my defense, I was just trying to see if I could get the call to work...
When I pressed the HTML button in my browser:
POW!: java.security.AccessControlException: access denied (javax.sound.sampled.AudioPermission record)
This was a little unexpected - if the applet button was pressed, I recorded. If the HTML button was pressed, then I got a security error.
I Googled the world and found Bug 4406607 and Mozilla bug 60120
But somehow the answers within didn't seem satisfactory.
Then my searches hit gold: Java Access Control Mechanisms (pdf)
A very nice explanation of what was happening, with a simple answer: change my Java method that was being called by the JavaScript to the following:
public String doRecord() {
return AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
replayRecorder.startRecording();
return "recording started";
}
});
}
Now my applet records when I hit the HTML button. Sweet.
Labels:
AccessControlException,
AccessController,
Applet,
Java,
JavaScript,
PrivilegedAction SecurityManager
Friday, March 25, 2011
JavaScript notes: a Firebug puzzle
There it stood, written before me on the page "Globals created with var (those created in the program outside of any function) cannot be deleted."1
Yet in Firebug
How could this be happening?
If I reworked the code and ran it as a script in a web page, it gave me "this is a: 10", as expected.
After a bit of research (thank you, Google), I found the answer. Ironically in a blog entry about another book by the same author that was puzzling me now...
The solution is well worth reading, but I'll see if I can summarize it:
Of course this answer poses another question: why are global variables that are in code executed in an eval context deletable?
I think that the following code might propose an answer:
When you evaluate code you will possibly have variables added to your calling context that you might not want there. By marking them as deletable, you have a chance to clean them up. Now to work out how you can do this automatically...
Footnotes
1 Page 12, JavaScript Patterns by Stoyan Stefanov, September 2010: First Edition.
2 Fool! wasn't really part of the message: that is just how I felt when I saw the error.
Yet in Firebug
var a = 10;
delete a;
console.log("this is a: " + a);
consistently returned:ReferenceError: a is not defined (Fool!)2
How could this be happening?
If I reworked the code and ran it as a script in a web page, it gave me "this is a: 10", as expected.
After a bit of research (thank you, Google), I found the answer. Ironically in a blog entry about another book by the same author that was puzzling me now...
The solution is well worth reading, but I'll see if I can summarize it:
- Variables are in fact properties with a "don't delete" flag set.
- Variables declared in JavaScript code that would otherwise be global, when executed by an eval call are in fact deletable (the flag isn't set)!
- Those deletable variables are added to the calling object's variable object, for want of a better place to put them.
Of course this answer poses another question: why are global variables that are in code executed in an eval context deletable?
I think that the following code might propose an answer:
(function test() {
eval('var wtf = "wtf";');
console.log(wtf);
console.log(delete wtf); // true
})();
When you evaluate code you will possibly have variables added to your calling context that you might not want there. By marking them as deletable, you have a chance to clean them up. Now to work out how you can do this automatically...
Footnotes
1 Page 12, JavaScript Patterns by Stoyan Stefanov, September 2010: First Edition.
2 Fool! wasn't really part of the message: that is just how I felt when I saw the error.
Labels:
Firebug,
JavaScript
Location:
Melbourne VIC, Australia
Subscribe to:
Posts (Atom)