我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Swift中的HTTP请求体Request Bodies如何使用

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Swift中的HTTP请求体Request Bodies如何使用

本篇内容介绍了“Swift中的HTTP请求体Request Bodies如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

正文

在进行HTTPRequest请求发送前,我们稍稍改进一下我们的结构体,最后,我们将会以下面的信息输出:

public struct HTTPRequest {    private var urlComponents = URLComponents()    public var method: HTTPMethod = .get    public var headers: [String: String] = [:]    public var body: Data?}

在本节中,我们将着重讨论一下body属性,并对其进行改造。

通用化body

在HTTP简介那一节,我们了解到,一个请求体是原始二进制数据,但是,在与 Web API 通信时,这些数据有多种标准格式,例如 JSON 和表单提交。

我们可以将其概括为一种“给我们数据的东西”的形式,而不是要求此代码的客户手动构造其提交数据的二进制表示。

由于我们不打算对用于构造数据的算法施加任何限制,因此通过协议而不是具体类型来定义此功能是有意义的:

public protocol HTTPBody { }

接下来,我们需要一种方法从其中一个值中获取Data,并在出现问题时选择性地报告错误:

public protocol HTTPBody {     func encode() throws -> Data }

我们可以在这一点上停下来,但还有另外两条信息值得拥有:

public protocol HTTPBody {     var isEmpty: Bool { get }    var additionalHeaders: [String: String] { get }     func encode() throws -> Data }

如果我们能快速知道一个body是空的,那么我们就可以省去尝试检索任何编码数据和处理错误或空数据值的麻烦。

此外,某些类型的正文与请求中的header结合使用。 例如,当我们将值编码为 JSON 时,我们希望有一种方法可以自动指定 Content-Type: application/json 的header,而无需在请求中手动指定它。 为此,我们将允许这些类型声明额外的header,这些标头将作为最终请求的一部分结束。 为了进一步简化采用,我们可以为这些提供默认实现:

extension HTTPBody {    public var isEmpty: Bool { return false }    public var additionalHeaders: [String: String] { return [:] }}

最后,我们可以将我们的类型更新到这个新的协议中

public struct HTTPRequest {    private var urlComponents = URLComponents()    public var method: HTTPMethod = .get    public var headers: [String: String] = [:]    public var body: HTTPBody?}

空请求体 EmptyBody

最简单的HTTPBody是”无体“。有了这个协议,定义一个空请求体也是很方便的。

public struct EmptyBody: HTTPBody {    public let isEmpty = true    public init() { }    public func encode() throws -> Data { Data() }}

我们甚至可以将其设置为默认的主体值,从而完全消除对该属性的可选性的需要:

public struct HTTPRequest {    private var urlComponents = URLComponents()    public var method: HTTPMethod = .get    public var headers: [String: String] = [:]    public var body: HTTPBody = EmptyBody()}

数据体 DataBody

下一个明显要实现的主体类型是返回给定的任何Data值的主体。 这将用于我们不一定有 HTTPBody 实现但也许我们已经有Data值本身要发送的情况。

具体实现如下:

public struct DataBody: HTTPBody {        private let data: Data    public var isEmpty: Bool { data.isEmpty }    public var additionalHeaders: [String: String]    public init(_ data: Data, additionalHeaders: [String: String] = [:]) {        self.data = data        self.additionalHeaders = additionalHeaders    }    public func encode() throws -> Data { data }    }

有了这个,我们可以很轻松的将一个Data值封装进HTTPBody里:

let otherData: Data = ...var request = HTTPRequest()request.body = DataBody(otherData)

JSON体 JSONBody

在发送网络请求时,将值编码为 JSON 是一项非常常见的任务。 制作一个 HTTPBody 来为我们处理这个现在很容易:

public struct JSONBody: HTTPBody {    public let isEmpty: Bool = false    public var additionalHeaders = [        "Content-Type": "application/json; charset=utf-8"    ]    private let encode: () throws -> Data    public init<T: Encodable>(_ value: T, encoder: JSONEncoder = JSONEncoder()) {        self.encode = { try encoder.encode(value) }    }    public func encode() throws -> Data { return try encode() }}

首先,我们假设我们得到的任何值都会至少产生一些结果,因为即使是空字符串也会编码为非空 JSON 值。 因此,isEmpty = false

接下来,大多数服务器在接收 JSON 正文时需要 application/jsonContent-Type,因此我们假设这是常见情况,并在 additionalHeaders 中默认该值。 但是,我们会将该属性保留为 var,以防万一出现客户不希望这样的情况。

对于编码,我们需要接受一些通用值(要编码的东西),但最好不要让整个结构对编码类型通用。 我们可以通过将类型的泛型参数限制为初始化器来避免类型的泛型参数,然后在闭包中捕获泛型值。

我们还需要一种方法来提供自定义 JSONEncoder,以便客户有机会摆弄诸如 .keyEncodingStrategy 之类的东西。 但是,我们将提供一个默认编码器来简化使用。

最后,encode() 方法本身只是调用我们创建的闭包,它捕获通用值并通过 JSONEncoder 执行它。

其中一个的使用方法如下:

struct PagingParameters: Encodable {    let page: Int    let number: Int}let parameters = PagingParameters(page: 0, number: 10)var request = HTTPRequest()request.body = JSONBody(parameters)

这样,正文将自动编码为 {"page":0,"number":10},我们的最终请求将具有正确的 Content-Type 标头。

表单 FormBody

我们将在本文中看到的最后一种主体是表示基本表单提交的body。 当我们专门讨论多部分表单上传时,我们将保存文件上传以备将来使用。

表单提交正文最终为粗略的 URL 编码键值对,例如 name=Arthur&age=42

我们将从与我们的 HTTPBody 实现相同的基本结构开始:

public struct FormBody: HTTPBody {    public var isEmpty: Bool { values.isEmpty }    public let additionalHeaders = [        "Content-Type": "application/x-www-form-urlencoded; charset=utf-8"    ]    private let values: [URLQueryItem]    public init(_ values: [URLQueryItem]) {        self.values = values    }    public init(_ values: [String: String]) {        let queryItems = values.map { URLQueryItem(name: $0.key, value: $0.value) }        self.init(queryItems)    }    public func encode() throws -> Data {        let pieces = values.map {  }        let bodyString = pieces.joined(separator: "&")        return Data(bodyString.utf8)    }}

和以前一样,我们有一个自定义的 Content-Type 标头来应用于请求。 我们还公开了几个初始化器,以便客户端可以以对他们有意义的方式描述这些值。 我们还删除了大部分 encode() 方法,省略了 URLQueryItem 值的实际编码。

不幸的是,对名称和值进行编码有点模棱两可。 如果你仔细阅读关于表单提交的古老规范,你会看到提到“换行规范化”和将空格编码为 + 的内容。 我们可以努力挖掘并找出这些东西的含义,但在实践中,Web 服务器往往可以很好地处理任何百分比编码的内容,甚至是空格。 我们将走捷径并假设这是真的。 我们还将全面假设字母数字字符在名称和值中是可以的,并且其他所有内容都应该被编码:

private func urlEncode(_ string: String) -> String {    let allowedCharacters = CharacterSet.alphanumerics    return string.addingPercentEncoding(withAllowedCharacters: allowedCharacters) ?? ""}

使用 = 字符组合名称和值:

private func urlEncode(_ queryItem: URLQueryItem) -> String {    let name = urlEncode(queryItem.name)    let value = urlEncode(queryItem.value ?? "")    return "(name)=(value)"}

有了这个,我们可以解决 评论:

public struct FormBody: HTTPBody {    public var isEmpty: Bool { values.isEmpty }    public let additionalHeaders = [        "Content-Type": "application/x-www-form-urlencoded; charset=utf-8"    ]    private let values: [URLQueryItem]    public init(_ values: [URLQueryItem]) {        self.values = values    }    public init(_ values: [String: String]) {        let queryItems = values.map { URLQueryItem(name: $0.key, value: $0.value) }        self.init(queryItems)    }    public func encode() throws -> Data {        let pieces = values.map(self.urlEncode)        let bodyString = pieces.joined(separator: "&")        return Data(bodyString.utf8)    }    private func urlEncode(_ queryItem: URLQueryItem) -> String {        let name = urlEncode(queryItem.name)        let value = urlEncode(queryItem.value ?? "")        return "(name)=(value)"    }    private func urlEncode(_ string: String) -> String {        let allowedCharacters = CharacterSet.alphanumerics        return string.addingPercentEncoding(withAllowedCharacters: allowedCharacters) ?? ""    }}

和以前一样,使用它变得很简单:

var request = HTTPRequest()request.body = FormBody(["greeting": "Hello, ", "target": "????"])// the body is encoded as:// greeting=Hello%2C%20&target=%F0%9F%8C%8E

其他Body Other Bodies

您可以在 HTTP 请求中发送的正文格式多种多样。 我已经提到过,我们将来会更仔细地研究多部分请求,但是这种 HTTPBody 方法几乎适用于您会遇到的每一种请求体。

“Swift中的HTTP请求体Request Bodies如何使用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Swift中的HTTP请求体Request Bodies如何使用

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Swift中的HTTP请求体Request Bodies如何使用

本篇内容介绍了“Swift中的HTTP请求体Request Bodies如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!正文在进行HT
2023-07-05

Swift中的HTTP请求体RequestBodies使用示例详解

这篇文章主要为大家介绍了Swift中的HTTP请求体RequestBodies使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-02-03

Spring中的Http请求如何使用restTemplete实现

这篇文章给大家介绍Spring中的Http请求如何使用restTemplete实现,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。使用Spring的restTemplete进行Http请求/** rest templet
2023-05-31

Node.js中Request模块处理HTTP协议请求的基本使用教程

这里来介绍一个Node.js的模块——request。有了这个模块,http请求变的超简单。Request使用超简单,同时支持https和重定向。var request = require('request'); request('http
2022-06-04

如何使用golang中的net/http/cookiejar包处理HTTP请求中的Cookie

如何使用Golang中的net/http/cookiejar包处理HTTP请求中的Cookie在使用Golang编写网络爬虫或是进行HTTP请求时,经常需要处理网站返回的Cookie。为了简化Cookie的管理,Golang提供了net/h
如何使用golang中的net/http/cookiejar包处理HTTP请求中的Cookie
2023-11-18

spring cloud 中 如何使用HTTP请求远程服务

今天就跟大家聊聊有关spring cloud 中 如何使用HTTP请求远程服务,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、Feign 简介在spring Cloud Netfl
2023-05-31

如何使用golang中的net/http/httputil.DumpRequest函数打印HTTP请求信息

如何使用golang中的net/http/httputil.DumpRequest函数打印HTTP请求信息概述:在Golang中,可以使用net/http包提供的httputil.DumpRequest函数来打印HTTP请求信息。这个函数可
如何使用golang中的net/http/httputil.DumpRequest函数打印HTTP请求信息
2023-11-18

SpringBoot中如何使用@RestController注解实现http请求

本篇内容主要讲解“SpringBoot中如何使用@RestController注解实现http请求”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“SpringBoot中如何使用@RestContr
2023-06-08

如何使用golang中的net/http/httptest.NewRecorder函数模拟HTTP请求和响应

如何使用golang中的net/http/httptest.NewRecorder函数模拟HTTP请求和响应在开发和测试Web应用程序时,经常需要模拟HTTP请求和响应。Golang提供了net/http/httptest包来方便地模拟HT
如何使用golang中的net/http/httptest.NewRecorder函数模拟HTTP请求和响应
2023-11-18

如何在 .NET中使用Flurl高效处理Http请求

在.NET中使用Flurl可以高效地处理HTTP请求。Flurl是一个强大的HTTP客户端库,它封装了发送和处理HTTP请求的细节,使得发送HTTP请求变得简单和高效。下面是使用Flurl处理HTTP请求的步骤:1. 安装Flurl库:在V
2023-08-09

如何在Java中利用Request请求获取IP地址

如何在Java中利用Request请求获取IP地址?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。示例代码public class IpAdrressUtil { /**
2023-05-30

Angular中http请求模块的使用方法

这篇文章主要介绍了Angular中http请求模块的使用方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。首先模块引入import { BrowserModule } fro
2023-06-06

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录