检索salesforce实例URL而不是visualforce实例

时间:2012-02-20 22:52:01

标签: salesforce apex-code controllers visualforce

在visualforce页面中,我需要检索组织的salesforce实例的URL,而不是视觉强制URL。

例如,我需要https://cs1.salesforce.com而不是https://c.cs1.visual.force.com

这是我到目前为止所尝试的以及我得到的结果:

从VF页面访问Site全局变量:

<apex:outputText value="{!$Site.Domain}" />返回null

旁注:$Site.xxx中的所有内容似乎都会返回null

来自Apex控制器:

public String getSfInstance()
{
  return ApexPages.currentPage().getHeaders().get('Host');
}

public String getSfInstance()
{
  return URL.getSalesforceBaseUrl().toExternalForm();
}

分别返回c.cs1.visual.force.comhttps://c.cs1.visual.force.com

问题:如何检索我想要的内容:https://cs1.salesforce.com

8 个答案:

答案 0 :(得分:10)

这是我在Apex触发器中使用的东西

System.URL.getSalesforceBaseUrl().getHost().remove('-api' );

这给了我正确的网址

答案 1 :(得分:4)

这是一个已知问题,URL.getSalesforceBaseUrl()应提供此信息,但事实并非如此。然而,实际上这对功能影响非常有限。

他们的实例和顶点域是可互换的,因为请求不属于一个的URL会被重定向到另一个。

例如,如果您从cs1.salesforce.com搜索/ apex / myPage,您将被重定向到c.cs1 ...反之亦然,从apex域请求/ ID将被重定向到实例域(除非详细操作被覆盖了)

如果这对您没有帮助,则有一种解决方法,尽管非常难看:)创建一个自定义对象来存储基本URL并在插入/更新触发器之前创建,这会将baseURL字段设置为URL.getSalesforceBaseUrl().toExternalForm()。显然触发器是平台上唯一可以工作的地方(除了执行匿名之外没有多大用处)。设置应用程序时,在该表中插入一些内容,然后使用SOQL检索基本URL。

答案 2 :(得分:4)

这是一个Apex属性,您可以将其放入Utility类中,该类将可靠地返回组织的实例。使用此功能,您可以通过将“.salesforce.com”附加到实例来轻松构建组织的Salesforce URL:

public class Utils {

 // Returns the Salesforce Instance that is currently being run on,
 // e.g. na12, cs5, etc.
public static String Instance {
    public get {
        if (Instance == null) {
            //
            // Possible Scenarios:
            //
            // (1) ion--test1--nexus.cs0.visual.force.com  --- 5 parts, Instance is 2nd part
            // (2) na12.salesforce.com      --- 3 parts, Instance is 1st part
            // (3) ion.my.salesforce.com    --- 4 parts, Instance is not determinable

            // Split up the hostname using the period as a delimiter
            List<String> parts = System.URL.getSalesforceBaseUrl().getHost().replace('-api','').split('\\.');
            if (parts.size() == 3) Instance = parts[0];
            else if (parts.size() == 5) Instance = parts[1];
            else Instance = null;
        } return Instance;
    } private set;
}

// And you can then get the Salesforce base URL like this:
public static String GetBaseUrlForInstance() {

     return 'https://' + Instance + '.salesforce.com';

}

仅供参考:对于场景(1),4部分主机名中的第1个可能变得非常复杂,但您始终可以找到实例名称作为第2部分。对于那些感兴趣的人,方案1的语法遵循以下模式:

     <MyDomain>--<SandboxName>--<Namespace>.<Instance>.visual.force.com

答案 3 :(得分:3)

在这里你有一个相当不错的小片段,它确实应该为VisualforcePages做什么: - )

        String sUrlRewrite = System.URL.getSalesforceBaseUrl().getHost();
        //  Example: c.cs7.visual.force.com
        sUrlRewrite = 'https://'
                + sUrlRewrite.substring(2,6) 
                + 'salesforce.com'
                + '/'
                + recordId;

//返回:https://cs7.salesforce.com/00kM00000050jFMIAY

答案 4 :(得分:3)

这是一个不幸的平台缺点。 GetSalesforceBaseUrl()附带警告,包括:

  • 返回的协议(http vs https)为inconsistent
  • visualforce上下文会影响结果(正如您在子域中看到的那样)
  • 使用My Domain和Sandboxes也会影响结果,使字符串操作变得有风险,

获取真正的pod / instance端点的唯一可靠方法是使用Salesforce Identity API

这是您可以使用的memoized静态,可以缓解以上所有因素:

/**
 * Determines the true API hostname for a Salesforce org using the Identity API.
 * eg 'https://pod.salesforce.com' (most orgs)
 * eg 'https://custom.my.salesforce.com' (my domain)
 * eg 'https://custom--dev.pod.my.salesforce.com' (sandbox orgs)
 */
static public String protocolAndHost {
    get {
        if (protocolAndHost == null) {
            //memoize
            String uid = UserInfo.getUserId();
            String sid = UserInfo.getSessionId();
            String oid = UserInfo.getOrganizationId();
            String base = Url.getSalesforceBaseUrl().toExternalForm();

            //use getSalesforceBaseUrl within batches and schedules (not Visualforce), and fix inconsistent protocol
            if (sid == null) return base.replaceFirst('http:', 'https:');

            //within test context use url class, else derive from identity response
            PageReference api = new PageReference('/id/' + oid + '/' + uid + '?access_token=' + sid);
            String content = Test.isRunningTest() ? '{"urls":{"profile":"' + base + '"}}' : api.getContent().toString();
            Url profile = new Url(content.substringBetween('"profile":"', '"'));
            protocolAndHost = profile.getProtocol() + '://' + profile.getHost();
        }
        return protocolAndHost;
    }
}

答案 5 :(得分:0)

修复Alex_E片段:

    String sUrlRewrite = System.URL.getSalesforceBaseUrl().getHost();
    String sfBaseProtocol = System.URL.getSalesforceBaseUrl().getProtocol();

    //remove namespace
    integer firstDotPos = sUrlRewrite.indexOf('.');
    sURlRewrite = sURlRewrite.substring(firstDotPos+1);

    //replace visual.force with salesforce
    sURlRewrite = sURlRewrite.replace('visual.force', 'salesforce');
    sUrlRewrite = sfBaseProtocol+'://'+sURlRewrite;

serverURL = sUrlRewrite;

答案 6 :(得分:0)

这对我有用:

String sUrlRewrite = System.URL.getSalesforceBaseUrl().getProtocol() 
    + '://' + System.URL.getSalesforceBaseUrl().getHost() 
    + '/' + record.Id;

答案 7 :(得分:0)

这与正则表达式有关

public String getURL() {
    return String.format(
      'https://{0}.salesforce.com',
      new String[]{
        URL.getSalesforceBaseUrl().getHost().substringAfter('.').substringBefore('.')
      });
}