大茂名网

 找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 178|回复: 0

[【编导】] 谈一谈如何在用户离开页面时可靠地发送 HTTP 请求2022/12/26 8:35:36

[复制链接]

2万

主题

2万

帖子

9万

积分

钻石元老

Rank: 24Rank: 24Rank: 24Rank: 24Rank: 24Rank: 24

积分
98065
发表于 2022-12-26 08:35 | 显示全部楼层 |阅读模式

马上注册登陆,结交更多好友,享用更多功能,让你轻松玩转社区

您需要 登录 才可以下载或查看,没有账号?用户注册

x

您可能希望该请求的分派是同步的,之后我们将继续导航离开页面,而其他服务器成功地处理该请求。但事证明,情况并非总是如此。有几次,当用户执行导航到不同页面或提交表单等操作时,我需要发送带有一些数据的HTTP请求以进行记录。考虑这个在点击链接时向外部服务发送一些信息的人为示例:域名IP查询的具体问题可以到我们网站了解一下,也有业内领域专业的客服为您解答问题,为成功合作打下一个良好的开端!


="--"=""GPEBI('')EL('',()={("",{:"POST",:{"C-T":""},:JSON({:""})});});这里没有什么非常复杂的事情发生。该链接可以正常运行(我没有使D()),但在该行为发生之前,会在单击时触发POST请求。需等待任何形式的响应。我只是希望它被发送到我正在访问的任何服务。

乍一看,您可能希望该请求的分派是同步的,之后我们将继续导航离开页面,而其他服务器成功地处理该请求。但事证明,情况并非总是如此。

浏览器不保证保留打开的HTTP请求当浏览器中发生终止页面的情况时,并不能保证进程内的HTTP请求会成功(参见更多关于“终止”和页面生命周期的其他状态)。这些请求的可靠性可能取决于几个方面——络连接、应用程序性能,甚至外部服务本身的配置。因此,在这些时刻发送数据可能是不可靠的,如果您依赖这些日志来做出数据敏感的业务决策,那么这可能会带来一个潜在的重大问题。为了帮助说明这种不可靠性,我使用上面包含的代码设置了一个带有页面的小型E应用程序。单击链接时,浏览器会导航到,但在此之前,会触发POST请求。当一切都发生时,我打开了浏览器的络选项卡,并且我使用的是“慢3G”连接速度。一旦页面加载并且我已经清除了日志,事情看起来很安静:



1

但是一旦链接被点击,事情就会出错,当导航发生时,请求被取消。



2

这使得我们对外部服务是否能够处理请求缺乏信心。为了验证这种行为,当我们使用以编程方式导航时也会发生这种情况:

EBI('')EL('',()={+D();R,("",{:"POST",:{"C-T":""},:JSON({:''}),});+=;});论导航以何种方式或何时发生,以及活动页面何时终止,那些未完成的请求都有被放弃的风险。

但是为什么被取消了呢?问题的根源在于,默认情况下,XHR请求(通过或XMLHR)是异步且非阻塞的。一旦请求被排队,请求的际工作就会被移交给幕后的浏览器级API。由于它与性能有关,这很好——你不希望请求占用主线程。但这也意味着当页面进入“终止”状态时,它们有被遗弃的风险,法保证任何幕后工作都能完成。以下是G对特定生命周期状态的总结:

一旦页面开始被浏览器卸载并从内存中清除,页面就处于终止状态。在这种状态下没有新的任务可以启动,并且正在进行的任务如果运行时间过长可能会被杀死。

简而言之,浏览器的设计假设当一个页面被关闭时,没有必要继续处理它排队的任何后台进程。

那么,我们有哪些选择呢避免这个问题比较明显的方法可能是,尽可能地延迟用户操作,直到请求返回响应。在过去,通过使用XMLHR中支持的同步标志来现这一点是错误的。使用它会完全阻塞主线程,导致大量的性能问题——我在过去写过一些这方面的文章——所以这个想法甚至不应该被接受。事上,它正在退出平台(C80+已经删除了它)。相反,如果您打算采用这种类型的方法,那么比较好在响应返回时等待P解析。在它回来之后,您可以安全地执行该行为。使用我们之前的代码片段,它可能看起来像这样:

EBI('')EL('',()={D();W("",{:"POST",:{"C-T":""},:JSON({:''}),});THEN=;});这可以完成工作,但也有一些不小的缺点。首先,它会延迟所需行为的发生,从而损害用户体验。收集分析数据肯定会给业务(以及未来的用户)带来好处,但让当前用户为现这些好处而支付成本并不理想。更不用说,作为一个外部依赖项,服务本身的任何延迟或其他性能问题都会暴露给用户。如果分析服务的暂停导致客户法完成一项高价值的行动,那么所有人都是输家。其次,这种方法并不像它比较初听起来那么可靠,因为一些终止行为法通过编程延迟。例如,D()法延迟某人关闭浏览器选项卡。因此,它充其量只能涵盖为某些用户操作收集数据,但不足以全面信任它。

指示浏览器保留未完成的请求值得庆幸的是,有一些选项可以保留绝大多数浏览器中内置的未完成的HTTP请求,并且不需要损害用户体验。

使用F的标志如果在使用()时将标志设置为,那么相应的请求将保持打开状态,即使发起该请求的页面被终止。使用我们比较初的例子,它的现如下所示:

="--"=""GPEBI('')EL('',()={("",{:"POST",:{"C-T":""},:JSON({:""}),:});});当点击该链接并进行页面导航时,不会发生请求取消:



3

相反,我们得到的是一个(未知)状态,原因很简单,活动页面从来没有等待接收任何响应。像这样的一行程序很容易修复,特别是当它是常用浏览器API的一部分时。但是,如果您正在寻找一种功能更集中、界面更简单的选择,那么还有另一种方法,它际上具有相同的浏览器支持。

使用NB()NB()函数专门用于发送单向请求()。一个基本的现看起来像这样,发送一个带有字符串化JSON和“”C-T的POST:

B('',JSON({:""}));但是此API不允许您发送自定义标头。因此,为了让我们以“”的形式发送数据,我们需要做一些小调整并使用B:

="--"=""GPEBI('')EL('',()={=B([JSON({:""})],{:';=UTF-8'});B('',));});比较后,我们得到了相同的结果——即使在页面导航之后也允许完成的请求。但是还有一些事情可能使它比()更有势:以低先级发送。为了演示,当同时使用带有的()和B()时,N选项卡中显示的内容如下:



4

默认情况下,()获得“高”先级,而(上面称为“”类型)具有“比较低”先级。对于对页面功能不重要的请求,这是一件好事。直接取自B规范:

该规范定义了一个接口,[…]比较大限度地减少与其他时间关键操作的资源争用,同时确保此类请求仍然被处理并交付到目的地。

换句话说,B()确保它的请求不会妨碍那些对您的应用程序和用户体验真正重要的请求。

因为属性而被光荣提及值得一提的是,越来越多的浏览器支持属性。当附加到链接时,它会触发一个小的POST请求:

="::3000"="::3000"GOP这些请求标头将包含单击链接的页面(-),以及该链接的值(-):

:{'-':'::3000','-':'::3000''-':''},它在技术上类似于发送,但有一些明显的限制:

它严格限制在链接上的使用,如果您需要跟踪与其他交互相关的数据,例如按钮点击或表单提交,这将使其法启动。

浏览器支持很好,但不是很好。在撰写本文时,F特别没有默认启用它。

您法随请求一起发送任何自定义数据。正如前面提到的,您比较多只能得到几个-*头文件,以及随程序一起出现的任何其他头文件。

综合考虑,如果您可以发送简单的请求并且不想编写任何自定义JS,那么是一个很好的工具。但是,如果您需要发送更多质内容,则可能不是比较好的选择。

那么,我应该选择哪一个呢?使用和或B()发送您的比较后一秒请求肯定存在权衡。为了帮助辨别哪种方法比较适合不同的情况,需要考虑以下几点:

如果出现以下情况,您可能会使用()+:

您需要轻松地随请求传递自定义标头。您想向服务发出GET请求,而不是POST。您正在支持较旧的浏览器(如IE)并且已经加载了。但在以下情况下B()可能是更好的选择:

您正在进行简单的服务请求,不需要进行太多定制。您更喜欢更简洁、更雅的API。您希望确保您的请求不会与应用程序中发送的其他高先级请求竞争。原文:-------作者:AMA
爱上大茂名,喜当大猫友,吃喝玩乐事,天天乐开怀!
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

QQ|客服:0668-2886677QQ:75281068|大茂微博|小黑屋|手机版|Archiver|大茂名网 ( 粤ICP备18149867号 )茂名市大茂科技有限公司 版权所有 

GMT+8, 2024-11-29 12:34 , Processed in 0.079352 second(s), 8 queries , Redis On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表