【问题标题】:Treat Salesforce VisualForce Page as an External Widget将 Salesforce VisualForce 页面视为外部小部件
【发布时间】:2011-10-20 20:43:44
【问题描述】:

我想将 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,但像这样的网址只会让我跳转到 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 页面。但这感觉很笨拙且不受支持。

现在我正在考虑创建一个可公开访问的新站点,以公开我的小部件。至少我可以放心地筛选那个页面。

感谢任何帮助。我现在打算使用匿名网站方法。

【问题讨论】:

    标签: screen-scraping salesforce apex-code visualforce


    【解决方案1】:

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

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

    这是一个示例 REST Web 服务。我只是在这里返回Map<String,String>,但您可以返回任何原始类型、任何 sObject 或原始或 sObject 的 List 或 Map(只要 Map 具有 String 键) - 请参阅 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;
        }
    }
    

    这里有一些 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');
        }
    }
    

    【讨论】:

    • 很好的答案;这是一种更好的做事方式。
    • 现在看起来一流。这个周末我会试试看。谢谢!
    • 不客气!如果一切顺利,请将复选标记移至此答案,以便我们推广最佳实践:-)
    • 哇!这真的让我看到了远远超出简单小部件的可能性。但是,它也适用于小部件。现在我在 XML 中返回 List (我将 HTTP Accept 设置为 application/xml,因为在 C# 中解析服务器端对我来说更容易)。我想我最终会返回一串轻微格式化的 html。这样我就可以从 Salesforce 操作表示层(在我的情况下是理想的,因为我在一个由 COM 可调用包装器向老式 ASP 公开的 dll 中——非常适合与 API 交谈,但不适用于演示)。感谢 metadaddy 的课程!
    • 一些提示给第一次看到这个非常有价值的 Salesforce 功能的人。你只会得到一个@HttpGet 方法,它的名字并不重要。您的 APEX 类必须至少是 22 版(我为此苦苦挣扎,但最终将 Force.com IDE 更新到最新版本并在 Eclipse 中打开 MyClassName.cls-meta.xml 将 apiVersion 元素更改为 23)。在 C# 中使用 WebRequest 非常容易。 var req = WebRequest.Create(url); req.Headers.Add("授权:OAuth" + sid); req.Accept = "应用程序/xml"; req.GetResponse() 你是金子。
    【解决方案2】:

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

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

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

    【讨论】:

    • 谢谢,马修。我让它与那个网址一起工作。我必须在第一个请求和第二个请求之间共享一个 CookieContainer,以便进行身份验证——但它起作用了!我想你不知道 frontdoor.jsp 是否需要一个重定向参数,我可以在一个请求而不是两个请求中完成它?
    • 我尝试了 retURL 参数并收到一条错误消息,提示我必须启用 javascript(我使用的是 c# 和 HttpwebRequest)。 CookieCollection 和两个请求运行良好。再次感谢。
    • 不客气!不幸的是,我尝试了 retURL 和 startURL 参数,但我也无法使用它们。
    • 请不要对 Visualforce 进行屏幕截图 - 有更好的方法来做到这一点 - 请参阅我的答案...
    • @BhavikPatel 您的评论可能最好作为一个新问题提出;这样你会得到更多的回应。
    【解决方案3】:

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

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

    【讨论】:

    • 我认为你是对的,因为我愿意咬掉更大的 Salesforce 站点。但在这种情况下,我追求的是“小部件”。如果你愿意的话,婴儿步骤。要从网站中获取小部件,我可以 IFrame 或屏幕抓取它——两者都感觉很笨拙。我将按照 metadaddy 的建议设置自定义 REST Web 服务。不过还是谢谢。
    猜你喜欢
    • 1970-01-01
    • 2021-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多