You might already know about it, but I think It's still worth mentioning, the common issue some developers stumble on:
1. GET
Requests Caching on Browsers
Sometimes, when making repeated GET XMLHttpRequest
to the same uRL can lead to the response coming from the browser cache and not from the server. Especially when you're using Internet Explorer. And this IS annoying.
With no-cache
or similar HTTP headers, this problem can be solved, theoritically, but in a real life coding this cache is sure difficult to get rid off.
The most effective way to solve this problem is add an always update or random variable to the URL where the request is sent. So the browsers read this request as a different page request and returns the server page rather than the cached version.
So, if usually we send a request like this
var url="somescript.php?var1="+var1;
XMLHttp.open("GET", url);
Now we just simply add a random varible like this
var url="somescript.php?var1="+var1+"&rand="+new Date().getTime();
XMLHttp.open("GET", url, true);
2. Escaping Variables
Remember, when creating GET
or POST
requests, you must escape every variables that have possibility to contain nontext characters or spaces. It's a good way to avoid crafted variables by people who like to mess or just test your codes. It goes simply like this:
XMLHttp.open("GET", url+escape(var1)+"?rand="+new Date().getTime(), true)
3. Permission Denied
Usually means that you have cross-domain scripting requests happen. Like what I've wrote earlier, an XMLHttpRequest object can't be made across different domains by default due to security matter. So by default, calls must be made to server scripts existing in the same domain as the calling scripts. And please notice that domain must be written EXACTLY in the same way, mydomain.com
may be interpreted as different domain from www.mydomain.com
, thus, permission will be denied. Here and here, you can find out how to solve this cross-domain issue.
Ajax Programming Common Errors
Friday, July 18, 2008Cross Domain Scripting with AJAX, Again
Thursday, July 17, 2008I've wrote about how to overcome the cross-domain issue using Apache mod_rewrite. But that'll only work if you have administrator priviledge on your hosting server, most of us don't. So instead of tweaking the server we must tweak the code. Thus, JSON shows up.
JSON(JavaScript Object Notation) is just a way to structure object data.. in a way that is easily interpreted, primarily with Javascript. Some examples from wikipedia:
Javascript
bork({"menu": { "id": "file", "value": "File", "popup": { "menuitem": [ {"value": "New", "onclick": "CreateNewDoc()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"} ] } }});
and with different format:
XML :
<menu id="file" value="File"> <popup> <menuitem value="New" onclick="CreateNewDoc()" /> <menuitem value="Open" onclick="OpenDoc()" /> <menuitem value="Close" onclick="CloseDoc()" /> </popup> </menu>
Aha, so just like xML, JSON is just data representation part of things, but if XML can't handle cross-domain scripting, how can JSON ?
It's because the J letter on JSON, JSON is JavaScript. And we all(well, maybe not all) know that you can reference REMOTE Javascript source inside the
<script>
tag. So theoritically, if you create a dynamic script tag that references to a script on another domain, that script is executed imediately!. And if the remote script contains JSON, your cross-domain scripting problems days are over!. Yay.
For an even easier way, you can use a js file at Dan Theurer's blog for the dynamic adding of scripts elements.
And here's how you use it.
First, a server side file that creates the JSON outputs, named
bork.php
<?php echo 'bork({"Image": { "Width":500, "Height":250, "Title":"Giant Cow", "Thumbnail":{"Url":"http://someurl.com/image/1234", "Height": 75, "Width": 150}}});'; ?>
And the html file ,
bork.html
<html> <head> <title>JSON test</title> <script src="jsr_class.js" type="text/javascript"></script> <script> function appendScript(){ var json=new JSONscriptRequest('http://myotherdomain.com/bork.php?'); json.buildScriptTag(); json.addscriptTag(); } function bork(data){ var txt=''; if(data==null) alert('error occured'); else{ txt='Image Title: '+data.Image.Title+'
'; txt+='Width: '+data.Image.Width+'
'; txt+='Height: '+data.Image.Height+'
'; txt+='Thumbnail Data: '+data.Image.Thumbnail.Url; txt+='('+data.Image.Thumbnail.Width+' x '+data.Image.Thumbnail.Height +')
'; } document.getElementById('bork').innerHTML=txt; } </script> </head> <body> <div id="bork"></div> <a href="#" onClick="appendScript();return false;">Get Bork</a> </body> </html>
Hope this helps.
Printer-Friendly Page With CSS
Monday, July 7, 2008Ok, so you want to create a printer-friendly page without having to create another web page for that purpose. Here's how.
First, create a separate stylesheet with the rules for the page to be printed. Usually, this css is named print.css
, so maybe you should name your it print.css
too :D.
Second, link the stylesheet to the page and set the media
property to print
.
<link rel="stylesheet" type="text/css" href="base.css" media="screen" />
<link rel="stylesheet" type="text/css" href="print.css" media="print" />
You see, the default value for the media
attribute is all
, so if you don't specify the attribute the browser will apply the CSS rules to all media. There are actually ten media types:
Media Type | Description |
---|---|
all |
Suitable for all devices |
braille |
For Braille tactile feedback devices |
embossed |
For paged Braille printers |
handheld |
For handheld devices |
print |
For paged material, documents viewed on-screen in print preview mode |
projection |
For projected presentation, i.e projectors |
screen |
Primarily for color computers screens |
speech |
For speech synthesizers |
tty |
For media using fixed-pitch character grid i.e teletypes, terminals, or devices with limited display capabilities |
tv |
For television-type devices |
If you want to define the stylesheet for several media, separate the media values with comma, like this
<link rel="stylesheet" type="text/css" href="dual.css" media="print, projection" />
And beside using
link
method, you can also use import
, like the following line
@import URI(dual.css) print,projection;
And stil there's way to define stylesheet and media types, it's by using the @media
, which enables writing css rules that can be set for different media, all in one stylesheet
<style type="text/css"> @media print{ #container { font-size: 10pt; background: #FFFFFF; color: #000000 } } @media screen{ #container { font-size: .8em; background: #0000FF; color: #FFFFFF } } </style>
Hope this helps.