在自定义 NSURLProtocol 中捕获 POST 参数
Posted
技术标签:
【中文标题】在自定义 NSURLProtocol 中捕获 POST 参数【英文标题】:Capture POST parameters in custom NSURLProtocol 【发布时间】:2019-03-22 10:27:36 【问题描述】:我有一个 NSURLProtocol 监听 UIWebView 上的 POST 请求。我尝试捕获 POST 参数并首先读取here,httpBody 始终为零,因为主体数据对象被转换为流式主体。
然后我使用以下扩展打开 HTTPBodyStream 对象并从中读取正文数据。
extension InputStream
func readfully() -> Data
var result = Data()
var buffer = [UInt8](repeating: 0, count: 4096)
open()
var amount = 0
repeat
amount = read(&buffer, maxLength: buffer.count)
if amount > 0
result.append(buffer, count: amount)
while amount > 0
close()
return result
问题是我从输入流中读取的 bodyData 也是 nil。在 MyUrlProtocol 中,我重写了以下方法。
override class func canInit(with request: URLRequest) -> Bool
if request.httpMethod == "POST"
print(request.url?.absoluteString) //ok show correct POST url
let bodyData = request.httpBodyStream?.readfully() //nil
print(String(data: bodyData!, encoding: String.Encoding.utf8))
return true
return false
override class func canonicalRequest(for request: URLRequest) -> URLRequest
return request
override func startLoading()
let bodyData = self.request.httpBodyStream?.readfully() //nil
override func stopLoading()
let bodyData = self.request.httpBodyStream?.readfully() //nil
为什么我的自定义 NSURLProtocol 中的 httpBodyStream 也是 Nil?
我可以在我的网络浏览器中使用网络开发工具正确查看同一 URL 的 POST 参数。
【问题讨论】:
检查是否在httpBody中设置? 再看你提到的答案。在 2018 年 1 月 18 日的评论中,作者解释了设置流代理以读取流所必须执行的步骤。 @SachinVas httpBody 也为零 @MikeTaverne 是的,这正是我在扩展中所做的,打开流并读取字节。这个扩展曾经可以工作,但我不知道为什么我不能再捕获 httpBodyStream 数据了 【参考方案1】:你不能像那样同步地从流中读取。您必须等待字节在流上可用,然后读取,然后再次等待,等等,直到其中一个读取返回零字节。如果没有等待部分,您就不会读取 while 内容,因为您读取数据的代码几乎肯定会阻塞应该填充流对另一端的线程。
这里描述了从流中读取的完整步骤:
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Streams/Articles/ReadingInputStreams.html
如果数据太大而无法放入 RAM,您可能需要在解析数据时将各个位写入磁盘,然后提供新的输入流。
无论哪种方式,您都必须异步执行。
【讨论】:
以上是关于在自定义 NSURLProtocol 中捕获 POST 参数的主要内容,如果未能解决你的问题,请参考以下文章
如何捕获 UIButton 事件:在自定义 UITableViewCell 实现中添加了 UIButton