You are currently browsing the monthly archive for January 2008.

Error: uncaught exception: Permission denied to call method XMLHttpRequest.open FireFox/Mozilla browser fix / solution:

  • Go to address “about:config” in Firefox (i.e. type that in the address bar and hit Enter)
  • Search for “signed” in the filter bar
  • Double click the item “signed.applets.codebase_principal_support” to change its value to “true”
  • Create (or edit if already present) the “user.js” file found in the below directories. By default this file does not exist so create a new blank user.js file if you don’t find it in the following paths (as specified on Mozilla.org):
    • On Windows Vista/XP/2000, the path is usually %AppData%\Mozilla\Firefox\Profiles\xxxxxxxx.default\, where xxxxxxxx is a random string of 8 characters. Just browse to C:\Documents and Settings\[User Name]\Application Data\Mozilla\Firefox\Profiles\ on Windows XP/2000 or C:\users\[User Name]\AppData\Roaming\Mozilla\Firefox\Profiles\ on Windows Vista, and the rest should be obvious.
    • On Windows 95/98/Me, the path is usually C:\WINDOWS\Application Data\Mozilla\Firefox\Profiles\xxxxxxxx.default\
    • On Linux, the path is usually ~/.mozilla/firefox/xxxxxxxx.default/
    • On Mac OS X, the path is usually ~/Library/Application Support/Firefox/Profiles/xxxxxxxx.default/
  • Place the following lines within user.js:

    user_pref("capability.policy.XMLHttpRequestToAnySite.XMLHttpRequest.open", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.sites", "http://localhost.com:3000");
    user_pref("capability.policy.XMLHttpRequestToAnySite.CDATASection.nodeValue", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Element.attributes", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Element.childNodes", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Element.firstChild", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Element.getAttribute", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Element.getElementsByTagName", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Element.lastChild", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Element.nodeName", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Element.nodeType", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Element.parentNode", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Element.tagName", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Element.nextSibling", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Element.previousSibling", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.HTMLCollection.length", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.HTMLCollection.item", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Text.attributes", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Text.childNodes", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Text.firstChild", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Text.getAttribute", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Text.getElementsByTagName", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Text.lastChild", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Text.nodeName", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Text.nodeType", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Text.parentNode", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Text.tagName", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Text.nextSibling", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.Text.previousSibling", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.XMLDocument.documentElement", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.XMLDocument.getElementsByTagName", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.XMLHttpRequest.channel", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.XMLHttpRequest.open", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.XMLHttpRequest.responseText", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.XMLHttpRequest.responseXML", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.XMLHttpRequest.send", "allAccess");
    user_pref("capability.policy.XMLHttpRequestToAnySite.XMLHttpRequest.setRequestHeader", "allAccess");
    user_pref("capability.policy.policynames", "XMLHttpRequestToAnySite");
  • Edit the line containing http://localhost.com:3000” and replace that URI with whatever URI you are developing on (or publishing to). For me it happens to be localhost.com:3000. Normally it would be just “localhost” for most people or localhost:3000 for Rails project developers.
  • Save the user.js file
  • Exit out of Firefox or other Mozilla based browser. If on Mac OS X, fully quit Firefox by hitting Cmd+Q, don’t just close the current browser window (which leaves Firefox still running in the background).
  • Launch FireFox again.
  • Exit out of Firefox again. The config file that Firefox actually uses to control the browser is called “prefs.js”, not “user.js”. user.js is the file that we, the end user, are supposed to make changes to, which are then copied over to prefs.js when Firefox is loaded. For whatever reason, the prefs.js file will not be updated with the contents of user.js until you exit Firefox, launch it, exit again (at which point prefs.js will be updated), then launch Firefox once more and your changes are ready for use.

After the above steps are completed, you should be able to make XMLHttpRequest calls cross-site / cross-domain with your AJAX code without Firefox/Mozilla security getting in the way.

The bevy of user_pref settings above creates a new site security policy that allows the listed XML HTTP Request commands to be performed from “http://localhost.com:3000” to any address. Normally, Firefox will only allow XMLHTTP Request calls within the same domain. For example if you were on microserf.com domain, Firefox would not allow the website http://www.microserf.com to make XMLHTTPRequest calls to http://www.hackmehard.com since this was a major exploit that crackers would use to hide their evildoings in the background of apparently benign sites.

In general the security policy that Firefox has setup by default is a good idea. Setting up a new security policy as we have done above is generally safe as it only allows the site “http://localhost.com:3000” to make cross-site/cross-domain XMLHTTPRequest calls of any sort listed. Any other domain would not be allowed to use this site policy.

This post originally started out due to the desire to develop Salesforce.com AJAX Toolkit based s-controls outside of their Ajax Tools IDE (yeah, their naming schemes leave something to be desired), which runs on their Force.com “no software” platform.  Of course I ran into huge problems with Camino / Firefox and cross domain XMLHTTPRequest scripting security issues.  The result of which is this post on how to get around the cross site scripting issues and develop javascript based s-controls on your local machine, using your preferred IDE (go go Textmate).

Update: This post has been superseded by How to Fix Ajax Error: permission denied to call method XMLHttpRequest.open.

For anyone developing S-controls and applications for use in Salesforce.com, developing directly within their platform is a bit of a hurdle. Using their Ajax Tools Development Environment for quick changes is fine. But, developing a serious piece of code purely using that tool is far from a pleasant reality today. Hence its natural to develop on a local machine then upload to Salesforce.com when a piece of software is ready for testing within the platform.

When trying to use the Ajax Toolkit connection.js library locally, you’ll encounter a cross domain scripting error:

“Permission denied to call method XMLHttpRequest.open”

Cross domain scripting is not allowed by default in Mozilla based browsers (Firefox, Camino, etc.).

To override this security feature you need to add the following line to your XMLHttpRequest code before issuing an open() call:

netscape.security.PrivilegeManager.enablePrivilege(“UniversalBrowserRead”);

This allows the user agent (browser) to ignore cross-domain scripting warnings, which are a major source of cracking attacks.

There are one or two more steps required to make this work depending on whether you’re using Firefox or Camino. The following step is the same for any Mozilla borwser, be it Firefox, Camino, or any other Mozilla based web browser agent.

In the browser address window type:

about:config

This opens the Mozilla configuration file which you can filter using the field at the top of the screen and edit items by double clicking on them.

Find signed.applets.codebase_principal_support
Top Secret!
By default it should be set to false. Double clicking it should set it to true.

For Firefox users, this next step is also necessary: adding a capability.policy line to the user.js config file which contains all user preference settings for the browser. Regardless of which operating system you’re using, user.js does not exist by default. Therefore, you must create this file, then add the appropriate settings into it. The settings from user.js get copied to prefs.js, which is the actual file read by Firefox.

On Mac OS X the correct directory to create this file within is:

~/Library/Application\ Support/Firefox/Profiles/[alphanums].default/

On Win XP or 200:
C:\Documents and Settings\[User Name]\Application Data\Mozilla\Firefox\Profiles\

See this Mozilla page on Editing config settings for more details and examples on locations for this file.

Note that [alphanums].default is a jumble of letters and numbers “dot” default and it is a directory. For example “o3dfi34z.default”. Within this directory create a file named “user.js”. Within this file add the following three lines:


user_pref("capability.policy.XMLHttpRequestToAnySite.XMLHttpRequest.open", "allAccess");
user_pref("capability.policy.XMLHttpRequestToAnySite.sites", "http://localhost.com:3000");
user_pref("capability.policy.policynames", "XMLHttpRequestToAnySite");

Now note that “http://localhost.com:3000” is only in my case. Whatever your local development location is, use that, be it “http://localhost”, “http://192.168.1.1”, etc. etc., use that. Be exact with this site address. It matters. For me, that port number was required for Firefox to allow me to send XMLHttpRequests to another domain without being denied.

Try running the XMLHttpRequest again and hopefully your Permission denied to call method XMLHttpRequest.open error has disappeared.

For those of you trying to use the Salesforce.com connection.js Ajax library locally, these are the following edits I made to make this happen. The following line numbers relate to version 11.1 of connection.js.

Find the definition of sforce.Transport, which should be around line 565.
Find the line: this.connection.open("POST", this.url, async); around line 591.
Add the following line before the previous line:

netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");

Change the relative URL paths for the Salesforce API from “/services/Soap/u/11.0” to the following:

"https://www.salesforce.com/services/Soap/u/11.1"

A nice way to do this is simply add a constant at the top of connection.js and just replace all occurrences of the relative path with this constant:

const sforce_api_url = "https://www.salesforce.com/services/Soap/u/11.1"

After that, fire up your trusty browser and try making your Ajax Toolkit call again.

You may find it helpful to use a Javascript development environment like Jesse Ruderman’s Javascript Development Environment 2.0.1 when playing around with Javascript. [Jesse, you’re the man]. Install it as a bookmarklet for the best user experience. It allows you to access all the javascript code and the document model in your current browser window through this development environment (which opens up in a new window).

Don’t forget the about:config stuff with the browser up above.

And finally, this is for debugging purposes on your local machine. Don’t publish code which disables security settings (which are there for a good reason) to a live deployment environment, such as Salesforce.com. Normally you’ll be installing the code you’re building as an S-control anyways, within the Salesforce.com platform, which will be exempt from any cross-site cross-domain scripting issues.

Z Movie Club, the sister site to Z Book Club (the online book club site) has been launched.

Z Movie Club is an online movies club site where you can browse, find and discuss movies online with other movie fans.

Z Movie Club is not a site where you can download films directly, but rather, use partner sites such as MovieLink, Blockbuster, NetFlix, Amazon to rent, purchase, or download movies or do all three.

I hope you find the site useful, interesting and enjoyable. Please stop by and check out some online movies at Z Movie Club.

Z Movie Club Online Movies Home

Online Movies at Z Movie Club - Club Page - V for Vendetta

If you notice some weirdness with Online Movies at Z Movie Club, apologies. I’m still smoothing out the kinks after the launch.

Have an .mkv movie file? Wondering what the heck it is and how to play it?

High Definition movies in 720 or 1080 pixel width format are often encoded and packaged as a Matroska format video with a .mkv file extension.

Apple QuickTime doesn’t handle this format natively so you have to add a package handler for mkv files to QuickTime to play .mkv files.

A quick and easy solution to how to play .mkv files is to install Perian, which makes QuickTime play .avi, .flv, and .mkv files and handles many different and popular encoding formats for video.

Perian for QuickTime

Remember to fully quit and re-launch QuickTime after installing Perian (don’t just close the QuickTime window, it’s still running until you Quit the program). This allows QuickTime to reload its list of handled formats and encodings.

When double clicking on an .mkv file to play it, you may have to wait until the entire film is buffered in QuickTime before it will play smoothly.  You can tell the progress of the buffering by looking at the grey timeline bar that is inching across the bottom left of the QuickTime window, starting near the 00:00 time marker. This is one of the oddities of the .mkv Matroska video package format. Don’t ask me why this happens, just keep this in mind next time you want to watch an mkv video on your Mac use Perian.