For example, if a local server outputs a JSON with sensitive information, and I can access it through my local network, can I access this data using a lightning component?
After a good deal of experimentation (I used this to gain my first practical bit of experience with LWC), the answer is yes.
Requirements
There are some requirements that need to be met:
- The local server needs to set, at the very least, the
Access-Control-Allow-Origin
header in the response to either the wildcard*
(not recommended), or the domain of your salesforce org (e.g.https:\\derekF.lightning.force.com
)- This is for CORS
- The local server needs to be able to provide the resource via https
- You don't need a trusted cert for this
- You need to add the local server's domain to your Salesforce CSP Trusted Sites
- The localhost domain can't be used for this, and the ".dev" tld is problematic (in Vivaldi/Chrome at least)
Local server setup (so you can replicate this)
- I installed XAMPP (doing this on win 10), and used "C:\xampp" as the install directory.
- I added a folder,
jsonTest
to the default directory that xampp serves out of, C:\xampp\htdocs - In C:\xampp\htdocs\jsonTest, I created a file
getjson.php
- In the apache extra config file
httpd-vhosts.conf
(C:\xampp\apache\conf\extra\httpd-vhosts.conf), I added a VirtualHost container withServerName local.devlp
- This isn't a domain I own, and the tld probably isn't valid either, but it works for proof of concept
- In the system's hosts file (C:\Windows\System32\drivers\etc\hosts), I pointed the loopback address (127.0.0.1) to
local.devlp
Proof of Concept
getjson.php
<?php
$testArray = [
"key1" => "value1",
"foo" => "bar"
];
header('Access-Control-Allow-Origin: ' . '*'); // this really should be something like 'https://mydomain.lightning.force.com'
print(json_encode($testArray));
Lightning Web Component (externalDataTest)
externalDataTest.html
<template>
<lightning-input label="URL" value={resourceURL} onblur={changeHandler}></lightning-input>
<lightning-card title="Response">
<p class="slds-p-horizontal_medium">From: {resourceURL}</p>
<p class="slds-p-horizontal_medium">{responseData}</p>
</lightning-card>
</template>
externalDataTest.js
import { LightningElement, track, wire } from 'lwc';
export default class ExternalDataTest extends LightningElement {
@track resourceURL;
@track responseData;
changeHandler(evt) {
this.resourceURL = evt.target.value;
// A plain ol' AJAX request, no fancy frameworks
var httpRequest = new XMLHttpRequest();
// Async and Javascript scoping is a bit weird if you're not used to it
// The anonymous function for onreadystatechange has access to local variables, but
// we can't reach responseData without some extra help (or, at least,
// I don't know how to do that).
// Inside the anonymous function for onreadystatechange, this = httpRequest
// So, to access responseData (which is normally done via this.responseData)
// we need to store the value of "this" in a local var
var that = this;
httpRequest.onreadystatechange = function(){
if(this.readyState === 4){
that.responseData = this.response;
}
}
// You could point this request to a static URL, if you're a COWARD (or if
// the url really is static, I guess)
httpRequest.open('GET', this.resourceURL);
httpRequest.send();
}
}
Result
Once you get the data into a javascript variable, the sky's the limit as to what you could do. One particular extension of this that I think would be interesting would be to pass data from a local/LAN/Intranet source back into Apex to create/update some records.
-
That's great! Thank you for taking your time to provide the answer with an example. That surely will help lots of people besides me. :) – Renato Oliveira May 16 '19 at 18:38
@auraenabled
. – Derek F May 15 '19 at 18:14