2

I have a JS library in a static resource. This library's code renders a with a Chatter Profile picture taken from the results of a

[SELECT FullPhotoUrl FROM User]

Or at least tries to.

This doesn't work as the JS is delivered from another subdomain

domain.na14.visual.force.com

than the Profile pics:

c.na3.content.force.com.

I get a

Unable to get image data from canvas because the canvas has been tainted by cross-origin data.

In a non-cloud world one would work with a proxy or set on the server:

access-control-allow-origin: [your site]
access-control-allow-credentials: true

Any ideas?!

  • Is javascript required for this solution? Could you just use a merge field and img tag? – Phil Rymek Mar 25 '13 at 16:17
  • Salesforce does not offer CORS configuration at this time. I have heard that they are exploring the possibility, but it has a lot of security implications to allow CORS and 'Trust' is one of the defining values of the company. – greenstork Mar 25 '13 at 16:28
5

I suspect you could use a relative URL to access the chatter profile picture. In the browser it silently behaves like this:

  1. Request of chatter picture: https://c.na11.visual.force.com/profilephoto/{id}/F
  2. Response of 302: https://na11.salesforce.com/profilephoto/{id}/F
  3. Response of 301: https://c.na11.content.force.com/profilephoto/{id}/F
  4. Request success: https://c.na11.content.force.com/profilephoto/{id}/F

Alternatively, you could leverage the native Salesforce proxy to perform this action as it was built for this cross domain purpose.

It is available at {sfdc domain}/services/proxy and the endpoint is configured in your organization in setup under Security Controls > Remote Site Settings. You would just give it a URL where the content resides such as https://c.na3.content.force.com

You would then be able to make a request from visual.force.com through the proxy to c.na3.content.force.com

A couple of articles that should provide enough insight to get you on your way.

  • Mark Pond: Your answer really sounds like a solution but I just don't get it. What do the 4 URLs tell me and why can't I understand the conntection between your text and the partly deprecated wiki links?! – Robert Sösemann Mar 25 '13 at 21:29
  • @RobertS I'll put together some sample code for both the relative URL scenario as well as the proxy scenario. – Mark Pond Mar 26 '13 at 16:12
1

Accessing other Salesforce orgs' information even with a proxy is going to be difficult (if not impossible as far as I know). Salesforce specifically prohibits callouts to it's own domains from APEX if I'm not mistaken. So that rules out service-side calls.

Furthermore, I think javascript is out of the question as well due to anti-cross domain browser security enforcements.

You might have to setup a remote proxy via Heroku or another hosted service for the easiest way to proxy between the two orgs.

  • Jordan: I am not accessing another orgs data! I want to pass the URL of a Chatter profile pic to a JS lib in a static resource zip. All in THE SAME org. Solving this with a Heroku proxy is like taking a sledgehammer to crack a nut ... – Robert Sösemann Mar 25 '13 at 21:30
  • What I think you're missing here @RobertS is an understanding of same origin policy, which applies even across different subdomains: en.wikipedia.org/wiki/Same_origin_policy -- A proxy server is one of the only things I could think of as well to maintain the callout from JS but I'll be curious if you can get Mark's relative links to work. – greenstork Mar 25 '13 at 21:53
  • 1
    Jordan: Salesforce does not prohibit callouts to its own domains, otherwise libraries like Metadata API from Apex would not be possible - but they are. – zachelrath Mar 26 '13 at 7:31
  • zachelrath: Then why does the HTML5 canvas code in my external JS library (provided as static resource from my org) throw this 'Unable to get image data from canvas because the canvas has been tainted by cross-origin data.' error when loading the FullPhotoUrl from a User? – Robert Sösemann Mar 26 '13 at 8:24
  • zachelrath - your right. but that's a metadata web-service. What I'm saying is your not going to be able to get a resource from another salesforce instance without authenticating and using an API, and even if you returned the URL for the chatter image, I doubt you could directly display it in another org...I'd be curious to see that, download the image from it's URL from the API > Display it in a VF page, and have the CDN deliver it! – jordan.baucke Mar 26 '13 at 21:29
0

I think your best option is to avoid using javascript for the callout and instead look into Connect for Apex:

http://blogs.developerforce.com/developer-relations/2013/02/getting-started-with-connect-in-apex.html

I've looked into setting up a remote proxy server on Heroku and it certainly makes what you're trying to accomplish possible, but it adds an extra layer of complexity.

  • Sorry fot voting this down. But if I ask how to make something work with a given JS library I am not amused by "Just get rid of JS" type answers. – Robert Sösemann Mar 25 '13 at 20:58
  • My only comment is, having not been aware of Salesforce's built-in proxy server to work across it's servers, that Javascript is risky from a security perspective for communication between a page and a server on different domains. So risky in fact, that all browsers prevent this cross-origin communication without an explicit setting from the server (CORS) allowing this type of communication, this is known as same-origin policy. In the absence of a proxy server, which I noted in my answer, this type of communication is impossible on Salesforce, hence what I believed a helpful recommendation. – greenstork Mar 25 '13 at 21:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.