Capability Delegation
Capability Delegation 可以简单理解成一种能力转交
某些在安全和体验上有特殊要求的API,需要在用户发生真实的交互事件后才能触发(譬如打开一个弹窗,播放Audio等等),如果用户点击和调用API是在同一个frame的上下文中,那自然是没有这个问题,那如果用户点击和调用APi是在两个Iframe里呢?
举一个典型的🌰
Payment Request API
The first specific use-case we want to support through our delegation mechanism is Payment Request API. Online stores that outsource payment related tasks to third-party services rely on this API.
To elaborate, there are many “middle-tier” merchants that are big enough to have their own shopping websites but not quite big enough to have their own payment infrastructure. They outsource the payment collection and processing infrastructure to Payment Service Providers (like Stripe) due to the considerable security and regulatory complexities around card payments. This creates a situation where the “pay” button is rendered inside the top (i.e. the merchant’s) frame where it can blend better with the rest of the merchant’s website, while the payment processing code is inside a cross-origin iframe from the PSP. A payment processing is initiated through a call to PaymentRequest.show() which requires transient user activation to prevent malicious attempts like unattended or repeated payment requests. Because the top (merchant) frame’s user interaction is not visible to the iframe, the PSP code needs some kind of a delegation in response to a click in the top frame to be able to use PaymentRequest.show().
We got a feature request recently (Jun 6 2019) that calls for the ability to delegate popup capability to an iframe; details are here. Any capability delegation mechanism would solve their use-case as long as there is a way to specify the “payment” capability.
大意就是,假如有一个电商站点,通常大家不会都去自己实现一遍支付的代码,毕竟工作量复杂,对安全和合规的要求也高。所以集成一个第三方的支付是很划算的。
但是我们的支付按钮一般都是在站点的frame里的,因为要保持UI风格的统一。而三方支付的页面是用iframe引入的。
例子中,PaymentRequest.show() 就是一个对安全性较高的API,需要用户点击之后才能调用。这个时候,按钮点击,是在电商页面里,API发起是在三方的页面里
要怎么把电商页面里的点击能力给到三方页面呢?
// 电商页面 button.onclick = () => { targetWindow.postMessage('a_message', {delegate: "payment"}); };
// 三方页面 window.onmessage = () => { const payRequest = new PaymentRequest(...); const payResponse = await payRequest.show(); ... }
相关链接:
https://chromestatus.com/feature/5708770829139968
https://wicg.github.io/capability-delegation/spec.html
浙公网安备 33010602011771号