When I query the chatter connect API through Javascript from a Visualforce page in a desktop browser, the post attachment URLs I receive use the visualforce domain that the page is being served up from, e.g.


If I use this as the background image via CSS, then the browser sends a cookie along with the request with the relevant authentication information. So far, so good.

Without a Cookie

If I don't have a cookie, say I just paste the URL into a different browser, then I can simply add a session id parameter to the URL (&sid=blahdeblahblah) and it also works. So far, still good.

From a Connected App

I have an iOS app that authenticates users through OAuth using the Salesforce Mobile SDK, and then it uses a method in the SDK to get an authenticated URL to the Visualforce page that I was previously accessing in the desktop browser.

Now, when the same javascript queries the Chatter connect API, the URLs returned are relative, and look like this:


and so if I try to use this as a CSS background image, the webview (WKWebView) attempts to load this URL:


And now things are not so good. The WKWebView does not send an authentication cookie along with this request and so it fails to load with an invalid session ID error, and I've been unable to find a URL parameter that I can add to this to make it work (I've tried sid, oauth_token and _bearer which all seem to have some use in various places).

Send Help!

I'm assuming the API is returning different URLs due to the session ID being used, because I can't seem to use a session ID from the iOS app in the first URL format. This rules out any cludgey solutions such as using a hard-coded URL.

So... Is there a way to either

1. set specific OAuth scopes to get URLs in the first format that will work? or,

2. use a session id parameter of some kind with the second URL format that won't give me a session ID error?

Failing either of these options I'm going to have to find some way to download the images via Javascript and the API and that just plain sucks.

Extra notes:

I'm using these OAuth scopes at present:

  • Access your basic information (id, profile, email, address, phone)
  • Access and manage your data (api)
  • Provide access to your data via the Web (web)
  • Provide access to custom applications (visualforce)
  • Perform requests on your behalf at any time (refresh_token, offline_access)

I previously had everything selected and hoped that by removing the Chatter option it might change the response URLs but no luck :(

  • So the only difference between the JavaScript requests is that one uses the SessionId from a browser cookie and the other a OAuth access token? Can you capture the raw HTTP requests with headers etc... ? I would have thought that with the web scope the requests would have been equivalent. – Daniel Ballinger Jan 6 '16 at 19:27
  • The web requests made by the web view are missing the auth cookies—I think that's an issue with the way the auth is done outside of that view or it's an iOS thing. Is there a URL parameter you can provide to scope the request that you know of? The URLs returned when using OAuth are designed to be used with headers set, but I can't do that for CSS background images. – Matt Lacey Jan 6 '16 at 22:30

Well I couldn't find a way to get the first style URL when using an OAuth initiated session, but I did find a way to make the CSS background-image work with the /services/data URLs.


Make an authorised (i.e. a request with the correct headers) JavaScript request to the Chatter API using the relative URL provided, e.g. /services/data/v33.0/chatter/files/06924000000NdruAAC/rendition?type=THUMB240BY180 before the div with the background image is rendered.


Job done. The prior request results in the image being cached for the URL, and so subsequent requests from CSS/<img> tags without the headers still get the cached result.


Yes, this is hacky. Ideally the binary data returned should be base64 encoded and used in an image Data URI, but then I'd need to deal with other issues such as working out the image format. This works for my approach works for my purposes and I'm in control of the environment, so I'm happy to use it. Be wary if you use this technique and you don't know what Browser/OS combo your users will be using.

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.