在自定义NSURLProtocol中捕获POST参数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在自定义NSURLProtocol中捕获POST参数相关的知识,希望对你有一定的参考价值。

我有一个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也是零。在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
    }

为什么httpBodyStream在我的自定义NSURLProtocol中也是Nil?

我可以在网络浏览器中使用网络开发工具正确查看POST参数的相同URL。

答案

您无法像这样同步地从流中读取数据。您必须等待流上的字节可用,然后读取,然后再等待,直到其中一个读取返回零字节。如果没有等待的部分,你就不会读取那些东西,因为你读取数据的代码几乎肯定会阻塞应该填充流对的另一端的线程。

此处描述了从流中读取的完整步骤集:

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Streams/Articles/ReadingInputStreams.html

如果数据太大而无法容纳在RAM中,则可能需要在解析它时将各个位写入磁盘,然后提供新的输入流。

无论哪种方式,您都必须异步进行。

以上是关于在自定义NSURLProtocol中捕获POST参数的主要内容,如果未能解决你的问题,请参考以下文章

如何捕获 UIButton 事件:在自定义 UITableViewCell 实现中添加了 UIButton

什么方法可以捕获在自定义视图(布局)中选择的上下文菜单项?

如何在自定义变体上捕获数组索引

Response.Redirect 在自定义 HttpModule 中使用 POST 方法

NSURLProtocol 详解

在自定义授权 MVC4 Web Api 中访问 post 或 get 参数