前端网络请求真的搞懂了吗?解密前端参数传递方式,让开发更从容(三)

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 前端网络请求真的搞懂了吗?解密前端参数传递方式,让开发更从容

前端网络请求真的搞懂了吗?解密前端参数传递方式,让开发更从容(二)https://developer.aliyun.com/article/1426379


如何将XML数据序列化为字符串

将 XML 数据序列化为字符串的过程被称为 “装串行”。

在 JavaScript 中,可以使用 XMLSerializer 序列化 Document 对象为 XML 字符串。

以下是一个将 XML 数据序列化为字符串的示例:

// 创建 XML Document 对象
const xmlDoc = document.implementation.createDocument("", "root", null);
// 添加子元素和属性
const person = xmlDoc.createElement("person");
person.setAttribute("id", "123");
const name = xmlDoc.createElement("name");
const text = xmlDoc.createTextNode("John");
name.appendChild(text);
person.appendChild(name);
xmlDoc.documentElement.appendChild(person);
// 将 Document 对象序列化为 XML 字符串
const serializer = new XMLSerializer();
const xmlString = serializer.serializeToString(xmlDoc);
console.log(xmlString);

以上代码中,首先使用 document.implementation.createDocument() 方法创建了一个名称为 “root” 的 XML Document 对象,并向其中添加了一个 “person” 元素和一个 “name” 子元素。然后使用 XMLSerializerxmlDoc 对象序列化为 XML 字符串,并将结果打印到控制台中。

需要注意的是,XMLSerializer 不会自动生成 XML 声明,开发者需要手动添加或使用 createDocument() 方法时传递。

此外,在服务器端,也可以使用相关的解析库将 XML 数据反序列化为 JavaScript 对象或其他数据类型。例如,在 Node.js 中,可以使用 xml2js 库对 XML 数据进行解析:

const xml2js = require('xml2js');
const xmlString = '<person id="123"><name>John</name></person>';
const parser = new xml2js.Parser({ explicitArray: false, trim: true });
parser.parseStringPromise(xmlString).then(result => {
  console.log(result);
});

以上代码中,使用 xml2js.Parser 类创建了一个解析器,并将 xmlString 作为参数进行解析,并将解析结果输出到控制台中。

如何在请求参数中传递和解析XML数据

在 Web 应用程序中,常常需要在请求参数中传递和解析 XML 数据。

以下是一些常见的方法:

1. 使用 GET 请求和 URL 参数传递 XML 数据:

const xmlDoc = document.implementation.createDocument("", "root", null);
const person = xmlDoc.createElement("person");
const name = xmlDoc.createElement("name");
const text = xmlDoc.createTextNode("John");
name.appendChild(text);
person.appendChild(name);
xmlDoc.documentElement.appendChild(person);
const urlParams = new URLSearchParams(new XMLSerializer().serializeToString(xmlDoc));
const response = await fetch('/api?data=' + encodeURIComponent(urlParams.toString()));

在这个例子中,XML Document 对象 xmlDoc 通过 XMLSerializer 序列化为字符串后通过 URLSearchParams 添加到 URL 参数中,最后使用 encodeURIComponent() 方法对参数进行编码处理,发送 GET 请求。

2. 使用 POST 请求和请求体传递 XML 数据:

const xmlDoc = document.implementation.createDocument("", "root", null);
const person = xmlDoc.createElement("person");
const name = xmlDoc.createElement("name");
const text = xmlDoc.createTextNode("John");
name.appendChild(text);
person.appendChild(name);
xmlDoc.documentElement.appendChild(person);
const response = await fetch('/api', {
  method: 'POST',
  headers: { 'Content-Type': 'application/xml' },
  body: new XMLSerializer().serializeToString(xmlDoc)
});

在这个例子中,XML Document 对象 xmlDoc 直接设置为 POST 请求的请求体内容,通过 headers 中指定的 Content-Type 通知服务器该请求体是一个 XML 数据。

在服务器端,可以使用对应的解析方法将 XML 数据反序列化为 JavaScript 对象。例如,在 Node.js 中,可以使用相关的解析库(如 xml2js)解析 XML 数据:

const http = require('http');
const xml2js = require('xml2js');
http.createServer((req, res) => {
  if (req.method === 'POST' && req.url === '/api') {
    let body = '';
    req.on('data', (chunk) => { body += chunk.toString(); });
    req.on('end', () => { 
      const parser = new xml2js.Parser({ explicitArray: false, trim: true });
      parser.parseStringPromise(body).then(data => {
        console.log(data);
        res.writeHead(200, { 'Content-Type': 'application/xml' });
        res.end(body);
      });
    });
  }
}).listen(8080);

以上是一个简单的 Node.js HTTP 服务器,当接收到 /api 的 POST 请求时,将请求体通过 xml2js 解析为 JavaScript 对象并输出到控制台,然后将其再次序列化为 XML 字符串并返回到客户端。

以上是一些常见的方法,通过这些方法,您可以在 Web 应用程序中轻松地传递和解析 XML 数据。

XML数据提交的使用场景

以下是 XML 数据提交的常见使用场景及其优势:

场景 优势
Web 服务 许多 Web 服务协议(如 SOAP)使用 XML 格式作为消息传递的格式。XML 支持复杂的数据结构和命名空间,能够描述数据的层次结构和类型信息,可帮助 Web 服务实现请求和响应的交互。
配置文件 在一些 Web 应用程序中,XML 格式用于配置文件记录应用程序的设置。使用 XML 格式保存配置信息,有助于使配置文件易于阅读和编辑,并且可以方便地进行版本控制和扩展。
数据存储 XML 数据可以存储在数据库中,作为一种结构化数据格式进行存储和检索。在一些 Web 应用程序中,XML 数据常用来存储和处理文档、模板和报表等结构化数据。
通讯协议 在某些情况下,XML 数据可以作为一种通讯协议传输,例如在传统的 Web Service 以及一些基于 REST 风格的 API 中,XML 作为数据格式可以使得多个系统之间通讯交流变得简单,适用于互联网上分散的多个系统。

在 Web 应用程序的开发中,XML 作为一种通用的数据交换格式,已被广泛应用于 Web 服务、配置文件、数据存储和通讯协议等领域。具有结构化、可扩展性、自描述性和跨平台互操作性等特点,使得 XML 数据格式能够适用于不同类型的数据描述和数据交换场景。

VIII. Hash参数

什么是Hash参数

Hash 参数是指 URL 中的 hash(#)后面带着的参数

当 URL 中的 hash 后面有参数时,称为 Hash 参数。

Hash 参数通常用于 Web 应用程序中的客户端路由和状态管理。

以下是一个示例 URI:

https://example.com/home?id=123#tab=info&section=contact

在 URI 中,https://example.com/home?id=123 是查询参数部分,而 #tab=info§ion=contact 则是 Hash 参数部分。Hash 参数后的字符串可以被 JavaScript 脚本解析和操作,而不会重新加载页面。这使得前端应用程序可以在不刷新页面的情况下加载特定状态的视图或组件。

在一些流行的前端框架和库中,如 Vue、React 和 AngularJS,都有使用 Hash 参数来实现客户端路由和状态管理的功能。在这些框架中,当应用程序切换到不同的路由或状态时,会更新 URI 的 Hash 部分,因此后退和前进按钮可以直接在应用程序中进行操作,而不会刷新整个页面。

如何在URL中添加Hash参数

要在 URL 中添加 Hash 参数,只需要在 URL 的末尾添加 # 符号和需要添加的 Hash 参数即可。

通常,Hash 参数格式为 #key1=value1&key2=value2...,其中 key=value 表示一个参数键值对。

以下是一个示例 JavaScript 代码,演示如何通过代码添加 Hash 参数到 URL:

const params = new URLSearchParams();
params.set('tab', 'info');
params.set('section', 'contact');
location.hash = params.toString();

在这个例子中,我们首先使用 URLSearchParams 类构造一个参数对象 params,并向其中添加了两个参数键值对 'tab'='info''section'='contact'。然后在 location.hash 中设置 Hash 参数的值为 params.toString(),即 tab=info§ion=contact,使浏览器 URL 的 Hash 部分被设置为我们所需的值。

除了使用上述的代码来添加 Hash 参数,还可以通过拼接字符串的方式将参数附加到 URL 的末尾。例如:

const url = 'https://example.com/page.html#' + encodeURIComponent('tab=info&section=contact');

在这个例子中,我们使用 encodeURIComponent() 方法将参数序列化为 URL 可用的格式,然后将其拼接到 URL 字符串的末尾形成完整的 URL。

需要注意的是,在添加 Hash 参数时,只是在 URL 中添加了一个用于客户端的标识符,服务端并不会收到这些参数。如果想要将参数发送到服务端进行处理,需要使用查询参数(query string)来传递参数。

获取Hash参数的方法

要获取 URLHash 参数,可以使用 JavaScript 中的 window.location.hash 属性获取当前页面的 URL 中的 Hash 部分。然后,可以将 Hash 值解析成对象形式,获取其中的参数。

以下是一个示例代码,演示了如何从页面 URL 获取 Hash 参数:

// 从 URL 获取 Hash 参数
const hashStr = window.location.hash.substring(1); // 去掉第一个字符 '#'
const params = new URLSearchParams(hashStr);
// 从 Hash 参数中获取具体的值
const tab = params.get('tab');
const section = params.get('section');
console.log(tab); // "info"
console.log(section); // "contact"

在这个例子中,window.location.hash 获取了当前页面的 URL 中的 Hash 部分,并使用 substring() 方法将其前面的 # 字符去掉。然后,使用 URLSearchParams 类构造一个参数对象 params,提取 Hash 参数中的数据。

由于 Hash 参数部分的格式通常为 #key1=value1&key2=value2...,因此 URLSearchParams 类通常可以方便地解析 Hash 参数到参数对象中。通过调用 params.get('参数名') 方法,可以轻松地获取参数的值。

需要注意的是,在某些旧版本的浏览器中,可能不支持 URLSearchParams 类,此时可以使用正则表达式或字符串分割等方式进行解析。

Hash参数的使用场景

以下是 Hash 参数的常见使用场景及其优势:

场景 优势
客户端路由 在单页应用程序中,使用 Hash 参数作为客户端路由的实现方式已经成为一种流行的方式。通过改变 URL 中的 Hash 参数来实现视图的切换,而无需刷新整个页面,提高了应用程序的交互性和响应速度。
状态管理 Hash 参数可以用来管理应用程序的状态,可以将状态编码到参数中,并在应用程序的不同片段之间进行传递。与客户端路由相结合,可以帮助应用程序保留状态信息以提供更好的用户体验。
分享链接 在一些应用程序中,Hash 参数用于保存用户输入的数据,或用户的浏览状态信息等。用户可以分享这些链接,以便其他人查看相同的内容或状态。
模块化加载 在一些模块化加载器(module loader)中,Hash 参数可以用于定义模块的版本或路径等信息,帮助加载器加载所需的模块并降低响应延迟。

在 Web 应用程序的开发中,Hash 参数已经被广泛应用于客户端路由、状态管理、数据共享和模块化加载等领域。

使用 Hash 参数作为客户端路由和状态管理的方式,可以实现无需刷新页面的视图切换和状态管理,并且可以大大提高应用程序的性能和用户体验。

此外,Hash 参数还可以用于分享链接和模块化加载等场景,为 Web 应用程序的开发和使用带来更多的便利。

IX. 入参方式的选择

分析每种方式的优缺点

对于客户端路由和状态管理这两种使用 Hash 参数的方式,它们的优缺点如下:

客户端路由

优点
  • 无需刷新页面:使用 Hash 参数可以实现无需刷新页面的视图切换,提高了应用程序的交互性和响应速度。
  • 可以使用浏览器历史记录:使用 Hash 参数来实现客户端路由,浏览器可以根据不同的 Hash 值来存储历史记录,用户可以使用浏览器的前进和后退按钮来导航应用程序的视图。
  • 易于实现:Hash 参数作为客户端路由的实现方式相对来说比较简单易懂,并且可以在不同的浏览器和设备上进行兼容性测试。
缺点
  • 安全性:Hash 参数可以被客户端 JavaScript 访问和修改,这可能导致某些安全问题。比如,恶意脚本可以修改 Hash 参数来篡改客户端路由和状态信息,这可能会影响用户的体验和应用程序的可靠性。
  • 可读性:由于 Hash 参数部分通常是一些密集的、难以阅读的字符串,因此它们不太具有可读性,这可能会给用户造成困惑或不便。

状态管理

优点
  • 可以保存应用程序的状态:Hash 参数可以用于保存应用程序的状态信息,比如选择的视图和用户的操作等,这可以大大提高应用程序的稳定性和可靠性。
  • 可以在应用程序的不同片段之间传递数据:Hash 参数可以在应用程序的不同片段之间传递数据,这可以减少服务器的负载,并且提高了应用程序的性能。
  • 易于实现:Hash 参数作为状态管理的实现方式相对比较简单,可以在不同的浏览器和设备上进行兼容性测试。
缺点
  • 依赖于客户端 JavaScript:Hash 参数作为客户端状态管理的实现方式,依赖于客户端 JavaScript,因此当用户禁用 JavaScript 或浏览器不支持时,这种方式将会失效。
  • 安全性:Hash 参数可以被客户端 JavaScript 访问和修改,这可能会导致某些安全问题。

总的来说,Hash 参数作为客户端路由和状态管理的实现方式,在应用程序开发中具有一定的优势和劣势,需要按照实际需求和具体情况进行权衡和选择。

根据场景选择最佳的入参方式

根据不同的场景,在选择最佳的入参方式时,可以考虑以下几个因素:

  1. 数据类型:入参可能是字符串、数字、布尔值、日期等不同的数据类型。需要选择一种能够支持处理所需数据类型的入参方式。
  2. 兼容性:入参方式需要在不同的浏览器和设备上进行兼容性测试,以确保在各种环境下均能正常工作。
  3. 安全性:需要考虑入参方式的安全性,以避免恶意脚本或攻击者篡改或伪造入参数据,从而导致数据泄漏或系统崩溃等问题。
  4. 可扩展性:在选择入参方式时,需要考虑其是否具有可扩展性,以便在未来的需求变更或功能扩展中能够适应新的需求。

基于以上考虑,下面是常见场景下的推荐入参方式:

  • URL 查询参数:适合需要从 URL 中获取简单的参数信息,例如在支付页面中使用订单号作为查询参数传递到后端。
  • POST 数据:适合需要传递复杂数据类型,例如在表单提交时,需要传递多个字段和内容比较多的文本数据。
  • Hash 参数:适合实现客户端路由或在单页应用程序中传递状态信息,例如使用 Hash 参数来标识不同的页面或状态。
  • 请求头参数:适合在 HTTP 请求中传递认证信息或应用程序的元数据,例如在请求 API 接口时,使用请求头参数传递 OAuth2 认证 Token。
  • Web 存储:适合在前端存储少量的数据或应用程序的缓存信息,例如使用 localStorage 存储用户在应用程序中选择的主题或语言信息。

在实际开发中,需要根据自身的需求和场景来选择最适合的入参方式。

防止攻击的代码实现技巧

在 Web 应用程序中,防止攻击是非常关键的一项工作。以下是几个常用的代码实现技巧:

1. 输入验证

对于所有输入数据,必须进行严格的验证和过滤,以确保输入的数据不包含任何恶意代码或特殊字符。例如,使用正则表达式来验证输入的数据格式,使用 HTML 编码来过滤特殊字符等。

2. 输出转义

在将数据输出到 HTML、CSS、JavaScript 或其他上下文中时,必须进行适当的转义,以避免脚本注入或其他攻击。例如,使用 HTML 实体编码来对特殊字符进行转义。

3. 数据库安全性

在进行数据库交互时,必须使用参数化查询和存储过程等安全措施,以避免 SQL 注入攻击或其他数据库攻击。例如,使用 PreparedStatement 类来执行参数化查询,使用存储过程限制用户对数据库的访问权限等。

4. 认证和授权

为用户提供安全的登录、身份验证和授权机制,以确保只有经过授权的用户才可以访问应用程序的功能和数据。例如,使用 OAuth2 或其他可信的身份验证和授权协议,使用密码哈希算法来保护用户密码等。

5. 安全头部

在应用程序中设置合适的安全头部,以帮助防御跨站点脚本(XSS)、点击劫持和其他攻击。例如,使用 Content-Security-Policy(CSP)头部来限制应用程序中可以使用的脚本和资源。

6. 日志记录

在应用程序中记录重要事件,例如登录失败、访问被拒绝等,以帮助监控和检测潜在的攻击行为。

以上技巧只是一些常见的防御方法,实际上还有许多其他的技巧和工具可以帮助保护 Web 应用程序的安全。在实际开发中,需要根据自身的需求和情况来选择最适合的防御措施,并且需要不断更新和评估这些措施,以保护应用程序不受到威胁。

X. 结论

总结各种入参方式的优缺点及其适用场景

入参方式 优点 缺点 适用场景
URL 查询参数 - 参数简单明了
- 可以被搜索引擎收录
- 易受 XSS 攻击
- 安全性差
传递少量的基本数据类型,如查询条件、页码等
POST 数据 - 传递复杂数据类型
- 安全性好
- 增加了服务器负担
- 需要跳转页面
传递较多数据或安全要求较高的数据项
Hash 参数 - 无刷新页面切换
- 可以使用浏览器历史记录
- 安全性差
- 可读性差
实现客户端路由或在单页应用程序中传递状态信息
请求头参数 - 安全性高
- 可以使用不同的请求体
- 需要比较繁琐的设置
- 难以调试
传递认证信息或应用程序的元数据
Web 存储 - 可以存储少量的数据
- 方便读取和设置
- 存储较多数据时性能不佳
- 安全性差
在前端存储少量的数据或应用程序的缓存信息

以上表格总结了常用的入参方式及其优缺点和适用场景,需要根据实际的需求和场景进行选择。需要注意的是,在代码中使用任何一种入参方式时,都需要进行相应的防御措施,以保护 Web 应用程序的安全。

推荐在实际开发中结合实际场景选择最优的入参方式

在实际开发中,需要结合具体的场景选择最优的入参方式,以下是一些常见的场景和推荐的入参方式:

  1. 传递少量的查询条件或状态信息时,可以使用 URL 查询参数或 Hash 参数。例如,通过 URL 查询参数传递搜索关键字或页面编号,或者通过 Hash 参数传递单页应用程序的状态信息。
  2. 传递大量或复杂的数据时,可以使用 POST 数据。例如,通过 POST 数据传递一个包含多个字段的表单,或者传递一个 JSON 对象以执行某些操作。
  3. 传递不需要公开的元数据或校验数据时,可以使用请求头参数。例如,在请求 API 接口时使用请求头参数传递 OAuth2 认证 Token 或者传递自定义的校验信息。
  4. 对于前端需要存储少量数据的场景,可以使用 Web 存储。例如,在前端存储一些用户配置信息或应用程序状态信息。

需要注意的是,在选择任何一种入参方式时,都需要进行相应的防御措施,以确保应用程序的安全性。如果不确定应用程序所传递的数据是否安全,建议使用 POST 数据或请求头参数传递数据,这样可以更好地保护数据的安全性。

相关文章
|
26天前
|
Linux 开发工具 Android开发
FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频
ijkplayer是由Bilibili基于FFmpeg3.4研发并开源的播放器,适用于Android和iOS,支持本地视频及网络流媒体播放。本文详细介绍如何在新版Android Studio中导入并使用ijkplayer库,包括Gradle版本及配置更新、导入编译好的so文件以及添加直播链接播放代码等步骤,帮助开发者顺利进行App调试与开发。更多FFmpeg开发知识可参考《FFmpeg开发实战:从零基础到短视频上线》。
100 2
FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频
|
3天前
|
API
鸿蒙开发:切换至基于rcp的网络请求
本文的内容主要是把之前基于http封装的库,修改为当前的Remote Communication Kit(远场通信服务),无非就是通信的方式变了,其他都大差不差。
鸿蒙开发:切换至基于rcp的网络请求
|
13天前
|
前端开发 JavaScript 安全
揭秘!前端大牛们如何高效解决跨域问题,提升开发效率!
【10月更文挑战第30天】在Web开发中,跨域问题是一大挑战。本文介绍前端大牛们常用的跨域解决方案,包括JSONP、CORS、postMessage和Nginx/Node.js代理,对比它们的优缺点,帮助初学者提升开发效率。
36 4
|
11天前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
|
1月前
|
负载均衡 前端开发 JavaScript
前端研发链路之开发
本文首发于微信公众号“前端徐徐”,作者徐徐。文章介绍了前端研发链路中的开发部分,重点探讨了开发服务器(dev-server)、热更新(hot-reload)、数据模拟(mock)和代理(proxy)等关键技术,帮助开发者理解其基本原理和应用场景,提升开发效率和代码质量。
34 2
前端研发链路之开发
|
1月前
|
XML 开发工具 Android开发
FFmpeg开发笔记(五十六)使用Media3的Exoplayer播放网络视频
ExoPlayer最初是为了解决Android早期MediaPlayer控件对网络视频兼容性差的问题而推出的。现在,Android官方已将其升级并纳入Jetpack的Media3库,使其成为音视频操作的统一引擎。新版ExoPlayer支持多种协议,解决了设备和系统碎片化问题,可在整个Android生态中一致运行。通过修改`build.gradle`文件、布局文件及Activity代码,并添加必要的权限,即可集成并使用ExoPlayer进行网络视频播放。具体步骤包括引入依赖库、配置播放界面、编写播放逻辑以及添加互联网访问权限。
129 1
FFmpeg开发笔记(五十六)使用Media3的Exoplayer播放网络视频
|
30天前
|
人工智能 前端开发 测试技术
探索前端与 AI 的结合:如何用 GPT-4 助力开发效率
本文介绍了 GPT-4 如何成为前端开发者的“神队友”,让开发变得更加高效愉快。无论是需求到代码的自动生成、快速调试和性能优化,还是自动化测试和技术选型,GPT-4 都能提供极大的帮助。通过智能生成代码、捕捉 BUG、优化性能、自动化测试生成以及技术支持,GPT-4 成为开发者不可或缺的工具,帮助他们从繁重的手动任务中解脱出来,专注于创新和创意。GPT-4 正在彻底改变开发流程,让开发者从“辛苦码农”转变为“效率王者”。
31 0
探索前端与 AI 的结合:如何用 GPT-4 助力开发效率
|
1月前
|
前端开发 JavaScript 开发者
前端angularJs的开发过程
前端angularJs的开发过程
19 1
|
2月前
|
前端开发 开发者 UED
前端只是切图仔?来学学给开发人看的UI设计
该文章针对前端开发者介绍了UI设计的基本原则与实践技巧,覆盖了布局、色彩理论、字体选择等方面的知识,并提供了设计工具和资源推荐,帮助开发者提升产品的视觉与交互体验。
|
30天前
|
JavaScript 前端开发 应用服务中间件
Vue开发中,在实现单页面应用(SPA)前端路由时的hash模式和history模式的区别及详细介绍
Vue开发中,在实现单页面应用(SPA)前端路由时的hash模式和history模式的区别及详细介绍
26 0