将 Salesforce VisualForce 页面视为外部小部件

发布于 2024-12-11 14:40:33 字数 1073 浏览 0 评论 0原文

我想将 Salesforce VisualForce 页面变成我公司网站的小部件。我想使用服务器端代码和服务帐户访问小部件。我将在我的网页中缓存、设置样式并输出小部件 html。我知道我可以使用服务器端代码和多个 API 调用来重现小部件,但我喜欢能够在 Salesforce 中管理小部件并让小部件可在 Salesforce 中的其他地方重用的想法。

在本例中,该小部件将报告我们在 Salesforce 中跟踪的竞赛中的当前领导者。我计划将这种方法重用于其他“迷你报告小部件”。这是一个非常有用的模式。我确信有人已经优雅地解决了这个问题。到目前为止,我的搜索一无所获。

我试图避免使用站点,因为访问我们公司网站的用户在 Salesforce 中没有用户帐户(现在我正在考虑允许匿名访问的站点)。

我的第一次尝试看起来像这样(受到 SSO 到自助服务门户的启发):

var ws = new sfapi.SforceService();
var lr = ws.login(Secrets.salesforce_user_name, Secrets.salesforce_password);
string url = "https://na6.salesforce.com/apex/mywidget?sessionId=" + lr.sessionId;

我也尝试了 ?sid 和 ?csssid,但是像这样的 URL 只会将我弹到 Salesforce 登录页面:

https://na6.salesforce.com/apex/mywidget?sessionId=00D3000000myorg!my-session-id-from-logging-in-with-the-api-8_i2fX_9wnYdwnwatGVuX6jGjmVmnv50j78yfGF1aKHdoDFtIx_J9

我可能可以使用标准屏幕抓取技术来发布到使用用户名和密码的标准 Salesforce 登录表单,然后拉出 /apex/mywidget 页面。但这感觉很笨拙且不受支持。

现在我正在考虑创建一个公开可用的新网站,只是为了公开我的小部件。至少我可以自信地屏幕抓取该页面。

任何帮助表示赞赏。我现在将尝试使用匿名网站方法。

I want to turn a Salesforce VisualForce Page into a widget for my corporate website. I want to access the widget using server side code and a service account. I'll cache, style, and output the widget html in my web page. I know I could just reproduce the widget with server side code and several API calls but I like the idea of being able to manage the widget in Salesforce and having the widget available for reuse elsewhere within Salesforce.

In this case, the widget is going to report on the current leaders in a contest we're tracking in Salesforce. I plan on reusing this approach for other "mini-report widgets." This is a very useful pattern. I'm sure somebody out there has elegantly solved it already. My searches have come up empty so far.

I was trying to avoid Sites because the user hitting our corporate website does not have a user account in Salesforce (now I'm thinking about a Site that allows anonymous access).

My first attempt looked like this (inspired by SSO to Self Service Portal):

var ws = new sfapi.SforceService();
var lr = ws.login(Secrets.salesforce_user_name, Secrets.salesforce_password);
string url = "https://na6.salesforce.com/apex/mywidget?sessionId=" + lr.sessionId;

I tried ?sid and ?csssid too, but urls like these just bounce me to the Salesforce login page:

https://na6.salesforce.com/apex/mywidget?sessionId=00D3000000myorg!my-session-id-from-logging-in-with-the-api-8_i2fX_9wnYdwnwatGVuX6jGjmVmnv50j78yfGF1aKHdoDFtIx_J9

I could probably use standard screen scraping techniques to post to the standard Salesforce login form with a username and password and then pull the /apex/mywidget page. But that feels clumsy and unsupported.

Now I'm thinking about making a new Site that is publicly available just to expose my widget. At least I could screen scrape that page with confidence.

Any help is appreciated. I'm going to play with the anonymous sites approach for now.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

聊慰 2024-12-18 14:40:33

将数据渲染到 Visualforce 页面,然后进行屏幕抓取似乎有点脆弱,更不用说效率低下 - 有更好的方法...

定义 Apex REST Web 服务,然后您可以轻松地从服务器端代码调用该 Web 服务,如果需要,仍然可以在 Visualforce 中渲染它 - 您可以像任何其他 Apex 方法一样调用 Apex REST 方法。

这是一个示例 REST Web 服务。我只是在这里返回一个 Map ,但是您可以返回任何基元类型、任何 sObject 或基元或 sObject 的列表或映射(只要 Map 具有 String 键) - 参见Apex REST Web 服务文档

@RestResource(urlMapping='/MyResource/*')
global with sharing class MyRestResource {
    @HttpGet
    global static Map<String,String> getResource() {
        Map<String,String> result = new Map<String,String>();

        result.put('key1', 'value1');
        result.put('key2', 'value2');

        return result;
    }
}

这是一些调用它的 PHP(我假设您有一个访问令牌(又名会话 ID)和实例 URL):

$url = "$instance_url/services/apexrest/MyResource";
$curl = curl_init($url);

curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER,
  array("Authorization: OAuth $access_token",
    "Content-type: application/json"));

$json_response = curl_exec($curl);

$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);

if ( $status != 200 ) {
    die("Error: call to URL $url failed with status $status, ".
      "response $json_response\n");
}

$response = json_decode($json_response, true);

echo "The service says ".$response['key1'].' '.$response['key2']."\n";

curl_close($curl);

这是一个 Visualforce 页面,如果你想显示相同的数据

<apex:page controller="TestRestController">
  <p>Controller says {!result}</p>
</apex:page>

页面控制器:

public class TestRestController {
    public String getResult() {
        Map<String, String> result = MyRestResource.getResource();

        return result.get('key1') + ' ' + result.get('key2');
    }
}

Rendering the data into a Visualforce page, then screenscraping it seems a bit brittle, not to mention inefficient - there is a better way...

Define an Apex REST web service, then you can easily invoke that web service from your server side code, and still render it in Visualforce if you need to - you can call an Apex REST method like any other Apex method.

Here's a sample REST web service. I'm just returning a Map<String,String> here, but you can return any primitive type, any sObject or a List or Map of primitives or sObjects (as long as the Map has String keys) - see the Apex REST Web Services docs

@RestResource(urlMapping='/MyResource/*')
global with sharing class MyRestResource {
    @HttpGet
    global static Map<String,String> getResource() {
        Map<String,String> result = new Map<String,String>();

        result.put('key1', 'value1');
        result.put('key2', 'value2');

        return result;
    }
}

Here's some PHP that calls it (I'll assume you have an access token (aka session ID) and instance URL):

$url = "$instance_url/services/apexrest/MyResource";
$curl = curl_init($url);

curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER,
  array("Authorization: OAuth $access_token",
    "Content-type: application/json"));

$json_response = curl_exec($curl);

$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);

if ( $status != 200 ) {
    die("Error: call to URL $url failed with status $status, ".
      "response $json_response\n");
}

$response = json_decode($json_response, true);

echo "The service says ".$response['key1'].' '.$response['key2']."\n";

curl_close($curl);

And here's a Visualforce page, if you want to show the same data

<apex:page controller="TestRestController">
  <p>Controller says {!result}</p>
</apex:page>

The page controller:

public class TestRestController {
    public String getResult() {
        Map<String, String> result = MyRestResource.getResource();

        return result.get('key1') + ' ' + result.get('key2');
    }
}
牵强ㄟ 2024-12-18 14:40:33

我不确定这是否适合您的目的,但您可以尝试一个 URL:

https://<endpoint host>/secur/frontdoor.jsp?sid=<session id>

加载该页面后,您可以重定向到小部件 url。

I'm not sure if this would work for your purposes, but there's a URL you could try:

https://<endpoint host>/secur/frontdoor.jsp?sid=<session id>

Once that page has loaded, you could redirect to the widget url.

百善笑为先 2024-12-18 14:40:33

听起来 Force.com 网站正是您想要的。

站点背后的想法是,它允许您无需登录即可访问 Visualforce 页面。

It sounds like Force.com Sites is exactly what you want.

The idea behind Sites is that it allows you access to Visualforce pages without having to have a login.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文