我正在我的前端使用条带JS库,只是设置令牌,而不是实际使用库。奇怪的是,当我加载任何页面条带时会产生一堆奇怪的请求,其中很多都是重复的。通常它看起来像这样:
https://m.stripe.com/4
https://m.stripe.com/4
https://stripensrq.global.ssl.fastly.net/s/e
https://stripensrq.global.ssl.fastly.net/s/o
https://m.stripe.com/4
然后,如果我使用History API更改页面状态,即使这是单页面webapp,它也会再次进行所有这些调用。这是正常的吗?
答案 0 :(得分:8)
这种行为也让我感到惊讶。如果您在SPA中的任何位置有import { loadStripe } from '@stripe/stripe-js
,从应用程序打开的那一刻起,Stripe就会在每次加载页面时开始打电话通知您。
从@ stripe / stripe-js v1.4.0开始,您可以使用/pure
导入路径,这会推迟Stripe库的负载,直到应用程序实际调用loadStripe
为止:
import { loadStripe } from '@stripe/stripe-js/pure';
一旦您调用loadStripe
,Stripe将在每次URL更改时继续向https://m.stripe.com/4
发送请求,直到浏览器通过HTTP请求(而不是通过JavaScript路由更改)导航到新页面或直到浏览器重新加载。
stripe.js作为其fraud detection mechanisms的一部分向https://m.stripe.com/4
发出请求。从@ stripe / stripe-js v1.5.0开始,您可以通过设置{advancedFraudSignals: false}
来禁用此行为:
import {loadStripe} from '@stripe/stripe-js/pure';
loadStripe.setLoadParameters({advancedFraudSignals: false})
const stripe = await loadStripe('pk_test_TYooMQauvdEDq54NiTphI7jx');
请注意,禁用此功能会增加接收欺诈性交易的风险。
如果您对其他详细信息感兴趣,我写了一篇关于此的博客文章:https://mtlynch.io/stripe-recording-its-customers/
答案 1 :(得分:1)
编辑:自编写此文档以来,Stripe更新了其库以解决这些问题,这在很大程度上归功于@mtlynch的出色调查工作。有关最新的答案,请参见上面的答案。
对于那些想要避免这种情况的人,似乎不是像文档所描述的那样导入Stripe库:
import { loadStripe } from "@stripe/stripe-js";
// when wanting to actually load Stripe this method is called,
// but `m.stripe.com` was fired on page load, before this was called
const publicKey = "yourPublicKey";
const stripe = await loadStripe(publicKey);
...这将自动调用m.stripe.com
端点,您可以动态导入库,以便仅在您确实需要Stripe功能时才调用该库(例如,在使用redux或vuex的情况下,不在每个页面上调用) ):
// create a new async function `stripeJs` that returns the library
const stripeJs = async () => await import("@stripe/stripe-js");
// later, we can call this before we need to use the library
// (e.g. in a vuex/redux action)
// STRIPE's TRACKING SCRIPT WILL BE CALLED NOW, RATHER THAN ON LOAD
const { loadStripe } = await stripeJs();
const publicKey = "yourPublicKey";
const stripe = await loadStripe(publicKey);
// example Stripe call
stripe.redirectToCheckout(...)
合理的警告,我不确定m.stripe.com
的作用,因此仅在执行该库之前导入该库可能会有意外的副作用,但这在我的测试中似乎可行。
答案 2 :(得分:0)
完全同意这里的其他答案。动态导入。
要更进一步,您可以考虑在同一来源的框架中运行付款处理,这意味着您可以在完成使用后强制卸载库。
// load this from wherever you want
const html = `
<!-- your external scripts and styles go here -->
<script src="https://js.stripe.com/v3/"></script>
<script>
const stripe = Stripe('{STRIPE_KEY}');
/**
* STRIPE IMPLEMENTATION GOES HERE
*/
// Once we've got a token we send it back to our app
stripe.createToken(/*{STRIPE_CARD}*/).then(({ token }) =>
parent.postMessage({ type: 'stripe-token', token }, '*'));
</script>
`;
// wait for the frame to load then write our body
iframe.addEventListener('load', () =>
iframe.contentWindow.document.write(html));
}
// add our iframe to the page and Stripe.js will load (and start pinging its server!)
document.body.append(iframe);
// wait for confirmation from the frame that we're finished with Stripe.js (see the html snippet above)
window.addEventListener('message', ({ data }) => {
if (data.type === 'stripe-token') {
console.log(data.token);
// we've got a token! We can remove our frame (and unload Stripe.js and all its telemetry!)
if (hasSrcdoc) iframe.srcdoc = '';
else iframe.src = '';
document.body.removeChild(iframe);
}
});
此处有完整的详细信息:https://codepen.io/theprojectsomething/full/ExVNEoZ