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.

Advertisements