学习目标
完成本单元后,您将能够:
- 描述在Salesforce Classic中运行的Visualforce页面与在Lightning Experience中运行的相同页面之间的三个区别。
- 描述需要更新才能在Lightning Experience中工作的两种常见代码模式。
- 在Lightning Experience中运行时,列出对Visualforce页面默认值的两个更改。
探索Visualforce应用程序容器
这种对执行上下文的更改对Visualforce页面可能影响整个Salesforce应用程序的方式有很多影响。我们将在这个单元中讨论这些变化,但是为他们自己的单位保存其中一些的全部细节。
外部闪电体验容器
我们从外部容器Lightning Experience应用程序开始。 Lightning Experience容器是一个“单页面应用程序”或SPA,可以在/one/one.app URL访问。 one.app页面加载,代码启动,应用程序代码接管环境。
单页面应用程序加载资源的过程(通常是静态的HTML shell和大量的JavaScript)既有趣又复杂。如果你已经使用了AngularJS或者React之类的JavaScript框架,那么你就非常熟悉以one.app的形式启动Lightning Experience的基础知识。说实话,完整的细节并不重要。你没有任何控制权,并且实现继续发展。
以下是重要的知识:Lightning Experience或one.app负责请求。您的Visualforce页面不是。您的页面需要在Lightning Experience强加给它的限制内工作。 Lightning Experience是父级环境,而Visualforce页面是子级环境。孩子需要服从父母。
其中一些约束条件(例如显示Visualforce页面的框架的大小)直接由Lightning Experience强制实施。他们更容易理解和使用,我们将在一分钟内讨论他们。
其他限制是隐含的,并不是由Lightning Experience实施,而是由运行它的浏览器实施。这些主要是安全性和JavaScript执行的限制。大多数页面不受这些安全约束的影响,而且那些通常会提前失败并带有明确的错误消息。 JavaScript错误很难发现和诊断,但是有一些通用的规则,我们稍后会介绍。
Visualforce iframe
当您的Visualforce页面在Lightning Experience中运行时,它将显示在HTML iframe中。一个iframe创建一个嵌入式浏览上下文,这个浏览上下文实际上是一个独立于主Lightning Experience浏览上下文的浏览器“窗口”。 iframe在Visualforce页面与其父项Lightning Experience应用程序之间创建一个边界。
在iframe中运行Visualforce页面的优点是,对于不需要访问或更改顶级浏览上下文的页面,在iframe中运行看起来几乎与Salesforce Classic中的页面一样运行。这就是为什么您不需要修改所有Visualforce页面以适应Lightning Experience的大量不同的幕后请求环境。这是支持Visualforce的“正常工作”策略的重要组成部分。
当然,另一方面是那些需要访问顶层浏览上下文的页面,还有一些需要改变的地方。我们将在下一节介绍一些细节。
如果您的页面与Salesforce之外的服务进行通信,则iframe边界也可能导致您需要更新组织的CORS设置,远程站点设置,clickjack设置或内容安全策略。由于这些依赖于Salesforce之外的安全策略和设置,因此我们无法提供特定更改的配方。我们在这里简单地提醒你注意。
新容器的影响
再一次,我们要强调的是:很多,甚至是大多数Visualforce页面都不会受到这些问题的影响。但是对于那些,我们认为“预先警告已经被警告”。如果我们已经一起讨论过,你会更快地发现问题的根源。
安全影响
可能受到影响的安全要素包括以下内容。
- 会话维护和更新
- 认证
- 跨域请求
- 嵌入限制
我们已经简要地讨论了一些这些涉及跨域请求的项目。也就是说,当完整的浏览器窗口中的内容来自对不同服务器和服务的请求时,这些请求中的任何一个都可能会妨碍在没有准备好的情况下显示。如果有需要,您的任务就是准备这些服务,以处理在闪电体验范围内的要求。正如我们之前所说,细节有所不同,所以我们不能在这里提供具体的答案。
有一件事我们特别要提的是会话维护。我们这里所说的“会话”基本上就是您的浏览器从请求到请求重用的一种令牌,这样您就不必为每个请求输入用户名和密码。您经常需要使用全局变量$ Api.Session_ID访问当前会话。
这是要记住的事情。 $ Api.Session_ID根据请求的域返回不同的值。这是因为每当您跨越主机名边界(例如.salesforce.com到.visual.force.com)时,会话ID都会在会话期间发生变化。通常情况下,Salesforce会透明地处理域之间的会话切换,但是如果您要传递会话ID,请注意,您可能需要从正确的域重新访问$ Api.Session_ID以确保有效的会话ID。
Lightning Experience和Visualforce页面不仅保存在不同的浏览器上下文中,而且也来自不同的域。因此,尽管它全部显示在一个浏览器窗口中,但Visualforce iframe中的会话ID将不同于iframe之外的会话ID,而在Lightning Experience的另一部分中。 Salesforce和Lightning Experience在正常使用情况下处理此透明。但是如果你在派对上通过会议ID(通常不是一个好主意),你可能需要回顾一下你是如何处理它的。
范围影响
当我们谈论范围时,我们主要谈论以下几种事情。
- DOM访问和修改
- JavaScript范围,可见性和访问
- JavaScript全局变量,如window.location
如果这个列表听起来很复杂或者令人困惑,不要担心,我们可以把它归结为简单易记的东西:不要碰别人的东西。具体而言,您的JavaScript代码(以及样式表规则)可能会影响页面浏览上下文中的元素(DOM节点,JavaScript变量等),但无法访问任何其他浏览上下文中的元素,闪电体验上下文。不要触摸其他上下文的东西!
实际上,你想要做这种事情的最常见的代码模式是操纵window.location导航到另一个页面。这是一个很常见的事情,我们已经写了关于这个特定问题的细节……当你完成这个模块的时候,你会厌倦听到这个问题,我们保证。
最后一个音符如果您是一位经验丰富的JavaScript开发人员,您可能已经在考虑通过使用contentWindow,window.parent等来了解如何处理“我无权访问父浏览上下文”问题。请不要。你可能会遇到同源策略(Visualforce和Lightning Experience来自不同的领域,请记住?)。即使你不这样做,你可能会用明显的,间歇性的错误代替显而易见的错误。你想在哪里花时间:做正确的事情,还是调试?
做正确的事情意味着调用我们在Visualforce页面中提供的API,主要用于导航。如果您确实需要跨越边界影响事物,请使用window.postMessage将消息发送到另一个帧中的接收代码。
Visualforce默认值和闪电体验的环境变化
其中一些变化很简单,一旦你想到它们,就很明显。例如,在Lightning Experience中运行的Visualforce页面始终具有标准的Salesforce Classic标题和侧栏。其他变化并不明显,但同样有很大的影响。
<apex:page> showHeader和侧栏属性始终为false
如果您的页面在Salesforce Classic和Lightning Experience之间共享,则仍然可以将这些属性设置为在Salesforce Classic中运行页面时要使用的值。
sforce.one JavaScript工具对象
尽管sforce.one听起来像一个在Salesforce cantina中工作的机器人,但它实际上是一个实用程序对象,它提供了许多有用的功能,您可以在自己的JavaScript代码中使用这些功能。
在Lightning Experience或Salesforce应用程序中运行时,sforce.one会自动注入您的页面。您将在您的JavaScript调试器控制台和Web开发人员资源列表中看到它。没有什么需要添加的,也没办法压制它。 (可惜的是,在Salesforce Classic的Visualforce页面中无法获取sforce.one。)
sforce.one主要用于消除导航事件。完整的细节在即将到来的单位,管理导航。
____________________
*没有Salesforce酒吧。唉。