js 在浏览器窗口关闭后还可以不中断网络请求

有个需求,我们需要在用户发送数据过程中,如果用户关闭了网页(包括整个浏览器关闭),不要中断数据传递

目前XMLHttpRequest对象是不支持的

http服务器

为了测试效果我们用nodejs写了个http服务器代码 文件名为httpServer.js如下,执行node httpServer.js就可以跑起来,支持get,post携带数据

// 导入http模块
const http = require('http');
var querystring = require('querystring');
// 创建Web服务器对象
const server = http.createServer();
// 监听端口号5005并启动HTTP服务器
server.listen(5005, () => {
    console.log('Web服务器启动成功啦!')
})

// 服务器实例通过.on()方法为服务器绑定request事件,监听客户端发来的请求,触发事件处理函数
server.on('request', (req, res) => {
    const version = req.httpVersion;
    const url = req.url;
    const method = req.method;
    console.log("收到请求:" + url + "method:" + method)
    res.setHeader('Content-Type', 'application/json');
    res.setHeader("Access-Control-Allow-Origin", '*')

    let info = { url: url, method: method }

    if (method.toLocaleLowerCase() == "post") {
        // 定义了一个post变量,用于暂存请求体的信息
        var post = '';

        // 通过req的data事件监听函数,每当接受到请求体的数据,就累加到post变量中
        req.on('data', function (chunk) {
            post += chunk;
        });

        // 在end事件触发后,通过querystring.parse将post解析为真正的POST请求格式,然后向客户端返回。
        req.on('end', function () {
            post = JSON.parse(post);
            info.body = post;
            console.log("post", post)
            // 调用res.end()方法向客户端响应一些内容
            res.end(JSON.stringify(info));
        });
    }
    else {
        // 调用res.end()方法向客户端响应一些内容
        res.end(JSON.stringify(info));
    }




})

终端效果

如果服务器收到网络请求,你的cmd或终端会看到如下的信息

我们写了三个网络请求函数

XMLHttpRequest请求

 function ajaxFn() {
            return new Promise((resolve, reject) => {
                var request = new XMLHttpRequest();

                request.open('get', request_url);
                request.send();
                request.onreadystatechange = function () {
                    if (request.readyState == 4) {
                        // console.log(request.responseText)
                        // console.log("ajax响应内容", request.responseText)
                        resolve(JSON.parse(request.responseText))
                    }
                }
                request.onerror = function (e) {
                    console.error("ajax跨域")
                    reject(2)
                }
            })
        }

调用方式

//XMLHttpRequest关闭窗口后不会发起网络请求
            ajaxFn().then(res=>{
                console.log("ajax响应内容",res)
            })

fetch请求 &&调用

//fetch 开启keepalive,可以发起网络请求,且不局限类型
            fetch(request_url, {
                method: 'post',
                keepalive: true,
                body: JSON.stringify({
                    'name': 'lili'
                })
            }).then(response => {
                response.json().then((data) => {
                    console.log("fetch响应内容",data);
                    return data;
                }).catch((err) => {
                    console.log(err);
                })
            })

 navigator.sendBeacon发送数据

  navigator.sendBeacon(request_url, JSON.stringify({ name: "sendBeacon" }), true);

为什么这里叫发送数据了,因为它不提供响应数据的回调函数,目标就是使用发送数据,只要服务器接口存在,关闭浏览器都不会影响继续发送数据

写个按钮,点击时候分不触发上面的函数,结果都可以发送数据

改为页面即将销毁时候触发上面函数

window.addEventListener('unload', function (event) {
            //触发函数
        });

结果XMLHttpRequest方式请求数据的方式,后台无法接受到数据

移动端兼容

unload事件在移动端上面不支持可以做以下判断

if (window.onunload) {
            window.addEventListener('unload', function (event) {
                //........
            });
        }
        else{
            document.addEventListener('visibilitychange', function logData() {
            if (document.visibilityState === 'hidden') {
                ///.....
            }
        });
 }

结论

使用navigator.sendBeacon场景:

  1. 传递少量数据
  2. 不考虑响应结果
  3. 只要求post请求方式
  4. 浏览器窗口关闭依旧发送数据
  5. 不会阻塞页面卸载,也就不会影响下一导航的载入
  6. 支持跨域(不关心数据响应,也没有跨域的顾虑,跨域是可以发送数据的,只是没法读取响应数据)
  7. 不支持自定义请求头

使用fetch keepalive

  1. 不考虑传递数据体积大小
  2. 大多数时候需要响应数据结果
  3. 任意请求方式
  4. 浏览器窗口关闭依旧发送数据&&不考虑响应结果

XMLHttpRequest
浏览器关闭后,不需要发送数据

参考

Navigator.sendBeacon() - Web API 接口参考 | MDN

Navigator sendBeacon页面关闭也能发送请求方法示例_javascript技巧_脚本之家

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/42941.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于深度学习淡水鱼体重智能识别模型研究

工作原理为:首先对大众淡水鱼图片进行数据清洗并做标签分类,之后基于残差网络ResNet50模型进行有监督的分类识别训练,获取识别模型。其次通过搭建回归模型设计出体重模型,对每一类淡水鱼分别拟合出对应的回归方程,将获…

Transformer 模型实用介绍:BERT

动动发财的小手,点个赞吧! 在 NLP 中,Transformer 模型架构是一场革命,极大地增强了理解和生成文本信息的能力。 在本教程[1]中,我们将深入研究 BERT(一种著名的基于 Transformer 的模型)&#…

Jmeter 如何并发执行 Python 脚本

目录 1. 前言 2. Python 实现文件上传 3. Jmeter 并发执行 4. 最后 1. 前言 JMeter 是一个开源性能测试工具,它可以帮助我们更轻松地执行性能测试,并使测试结果更加可靠。Python 是一种广泛使用的编程语言,它可以用于开发各种软件和应用…

017-从零搭建微服务-系统服务(四)

写在最前 如果这个项目让你有所收获,记得 Star 关注哦,这对我是非常不错的鼓励与支持。 源码地址(后端):https://gitee.com/csps/mingyue 源码地址(前端):https://gitee.com/csps…

数学建模入门-如何从0开始,掌握数学建模的基本技能

一、前言 本文主要面向没有了解过数学建模的同学,帮助同学们如何快速地进行数学建模的入门并且尽快地在各类赛事中获奖,或者写出优秀的数学建模论文。 在本文中,我将从什么是数学建模、数学建模的应用领域、数学建模的基本步骤、数学建模的技…

DevOps系列文章之 Git知识大全

这里是结合实际业务场景输出。 使用的 Git版本:git version 2.24.0 命令 git log 查看日志,常规操作,必备 # 输出概要日志,这条命令等同于 # git log --prettyoneline --abbrev-commit git log --oneline# 指定最近几个提交可以带上 - 数…

SpringBoot整合SpringData JPA

SpringBoot整合SpringData JPA 下一节直通车 JPA的一对一、一对多、多对多查询 简介 JPA(Java Persistence API)意即Java持久化API,是Sun官方在JDK5.0后提出的Java持久化规范(JSR 338,这些接口所在包为javax.persistence,详细…

【《Spring Boot微服务实战(第2版)》——一本关于如何在Spring Boot中构建微服务的全面指南】

使用Spring Boot框架构建基于Java的微服务架构,将应用程序从小型单体架构蜕变为由多个服务组成的事件驱动架构。这个最新版本围绕服务发现、负载均衡、路由、集中式日志、按环境配置和容器化等知识点,循序渐进地讲述微服务架构、测试驱动的开发和分布式系…

Mac 预览(Preview)丢失PDF标注恢复

感谢https://blog.csdn.net/yaoyao_chen/article/details/127462497的推荐! 辛苦用预览在pdf上做的阅读标记,关闭后打开全丢失了,推荐尝试下网站导入文件进行恢复: 直接使用该网页应用PDF Annotation Recovery 或者访问该项目&a…

下载|GitLab 2023 年 DevSecOps 全球调研报告:安全左移深入人心、AI/ML 蔚然成风

目录 谁应该对应用程序安全负主要责任? 安全实践的最大挑战 AI 驱动研发,提升研发效率 各个角色使用的工具数量是多少? 一体化 DevSecOps 平台有哪些优势? 56%、74%、71%、65%、57% 这些数字和 DevSecOps 结合在一起&#xf…

MySQL一些知识

六、MySQL命令参数 七、远程登录 use mysql 八、SQL语句和常见的SQL操作 九、数据库和表的创建及插入 指定字段名称,按照表的字段名称顺序写: 指定字段名称: 字段名称可以不全部指定:

K8s Service网络详解(二)

Kube Proxy Kubernetes 在设计之初就充分考虑了针对容器的服务发现与负载均衡机制。 Service 资源,可以通过 kube-proxy 配合 cloud provider 来适应不同的应用场景。 Service相关的事情都由Node节点上的 kube-proxy处理。在Service创建时Kubernetes会分配IP给Ser…

vue3-Vite原理

1. vite的优势 1. 极速的服务启动2. 轻量快速的预加载.....2. 对vite的理解(和webpack对比说明) webpack要经过打包,然后在开发阶段启动服务器vite不需要打包 下图的"准备"就是编译的意思。 css的内容会编译程一个字符串。 组件会…

海盗王基于golang重制版的商城服务端

海盗王原始的商城服务端,附带有很多其他功能(如GM留言管理,商品管理接口),配置起来非常麻烦,而且运行时问题也很多,经常会出现弹出停止响应,无法正常提供服务。 在很早的时候&#x…

系统架构设计师-软件架构设计(1)

目录 一、软件架构的概念 1、架构的本质 2、架构的作用 二、架构发展历史 三、架构的 “4 1” 视图 1、逻辑视图(Logical View) 2、开发视图(Development View) 3、进程视图(Process View) 4、物理视图…

【车载开发系列】AUTOSAR DemComponent和DemDTC

【车载开发系列】AUTOSAR DemComponent和DemDTC 【车载开发系列】AUTOSAR DemComponent和DemDTC 【车载开发系列】AUTOSAR DemComponent和DemDTC一. DemComponent概念二. DemDTC概念三. 常用设置参数DemDTCClass1) DemDTCFunctional2)DemDTCSeverity3&am…

ChatGPT开放自定义系统级别的指令,可设置偏好变成专属助理

OpenAI官方消息https://openai.com/blog/custom-instructions-for-chatgpt OpenAI为其大型语言模型接口ChatGPT引入了自定义指令,旨在为用户提供更加量身定制和个性化的体验,可以设置您的偏好,ChatGPT将在未来的所有对话中记住它们。 该功…

PhpStudy靶场首页管理

PhpStudy靶场首页管理 一、源码一二、源码二三、源码三四、源码四 一、源码一 index.html <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>靶场访问首页</title><style>body {background-color: #f2f2f2;colo…

Python采集某网站小视频内容, m3u8视频内容下载

目录标题 前言环境使用:模块使用:代码实现步骤代码展示尾语 前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 环境使用: python 3.8 运行代码 pycharm 2021.2 辅助敲代码 模块使用: import requests >>> pip install requests 内置模块 你安装好python环境就…

Clion开发STM32之W5500系列(NTP服务封装)

概述 在w5500基础库中进行封装&#xff0c;获取服务端的时间&#xff0c;来校准本地时间。本次使用的方案是通过ntp获取时间定时器更新保证时间准确。 NTP封装 头文件 /*******************************************************************************Copyright (c) [sc…