5

I have a jQueryUI widget that I'd like to use inside of a lightning app that makes some xhr requests. The xhr request fails without a server error code. I suspect that aura is preventing the call somehow. Does anyone have any insight into this?

The request is to the same domain that the standalone Lightning app is running in, so there shouldn't be any cross site xhr errors. If I hit the endpoint directly it works fine.

Thanks for any help!

  • I recognize that it would be best to write a new lightning component, but in the interest of time and avoiding a full rewrite I am attempting to reuse an existing jquery UI widget within my lighting component. – Scott Morrison Jul 15 '15 at 17:57
  • What is the actual domain of your XHR request? Is it really the same as the lightning component. Bear in mind LCF is hosted from the domain naX.lightning.force.com. Are you really making an XHR to that domain? – pchittum Jul 15 '15 at 20:29
7

It is difficult to know exactly what is wrong without some code, but I will take a stab based on a couple of assumptions:

  • You are making a classic XHR call either directly, or via jQuery.ajax()
  • You are requesting some Salesforce endpoint...most likely the Salesforce REST API endpoints found at https://XXXX.salesforce.com/services/data/v34.0 or perhaps your own Apex REST endpoint

A bit of history: Visualforce, the predecessor to Lightning Components, always ran in an iFrame when embedded in the standard UI (for instance an inline VF page in a page layout). This was a security measure to reduce the certain malicious attacks due to the VF page being compromised.

But this tied the hands of VF from being able to be a full-fledged member of the UI, making it difficult to use VF for small behavior changes (like modifying a single field on a page layout).

In comes Lightning Components. One of the promises (currently in pilot as Lightning Extensions) is for us to be able to do exactly these kind of very granular customizations. In order to do this Lightning Components could not be in an iFrame.

But to have unknown code sharing the UI with our code is a potential security risk.

To mitigate this security risk, Salesforce has put in place strict content security policy (aka CSP) for Lightning Components.

If you take a look at the Content-Security-Policy header for your lightning app you will see that the policy rule for XHR requests (connect-src) is set to self.

CSP Header as viewed from Chrome Tools on Standalone Lightning App

This means that any XHR would only be allowed by the browser to make requests to endpoints of the exact same domain as your Lightning App. For my org, I have a Lightning app running at this URL:

https://eu5.lightning.force.com/c/tabula.app

This means an XHR would only be allowed to endpoints that are in the domain eu5.lightning.force.com. No other endpoints would work. Not even other valid Salesforce endpoints like eu5.salesforce.com or c.eu5.visual.force.com.

In fact, the request won't even make it to the server. The minute you invoke the send method on your XHR, CSP will object very strongly. Here is a quick example using the browser console, attempting to put together an XHR to go to https://eu5.salesforce.com/services/data/v34.0/sobjects/account/describe.

CSP prevents connections to non-sanctioned domains

The long and the short of it is that the only way to connect to your Salesforce data today from LCF is an Apex method surfaced using @AuraEnabled that is invoked using the ActionService by creating an action instance and passing it to $A.enqueueAction.

Since the launch of LCF, the product team have spoken of implementing a way to whitelist additional endpoints in the future. CSP allows for exactly this functionality. But now we fall into the realm of forward looking statements, as this feature does not exist yet. And there are more than just technological obstacles: the Salesforce security and trust team would need to determine that a whitelist feature would not lead to additional security risks.

This may have been a lot of work if my assumptions above were wrong...but hopefully educational nevertheless.

  • You were right. I had to persist the log to see that it is in fact doing a redirect to a visualforce endpoint which causes the error. Interestingly chrome wasn't throwing the security policy error. Any idea if I can call a lightning controller from a non lightning script? – Scott Morrison Jul 16 '15 at 19:05
  • Well...it is all JS in the global window context...you could try instantiating a component inside your script, from the component instance, create the action, enqueue it and see if it works. Sounds messy, though. I'm literally just thinking out loud here. – pchittum Jul 16 '15 at 19:21
  • I ended up creating an application level event and adding a handler for the event which I can trigger from my external script. That worked beautifully. Thanks for the help! – Scott Morrison Jul 17 '15 at 16:23
  • So you're leveraging the Aura event structure? I noticed you had another question about this...make sure you circle back and answer your own question for others who may be struggling with it. – pchittum Jul 20 '15 at 8:32
1

Are you able to see any errors logged in the dev console? Salesforce utilizes jQuery internally so it's possible you're running into a conflict if your widget is using the $ alias without also calling jQuery's noConflict method

0

You can now whitelist CSP endpoints

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.