Add request header to ALL outgoing requests within a WKWebView
Asked Answered
F

2

6

TL;DR: I've got an iOS (Swift) project with a WKWebView. I want to add a request header to ALL outgoing requests (html, images, scripts, stylesheets, etc.) within this WKWebView. I can't find out how to do this.

Background:
I've got a Swift iOS application which uses a WKWebView to render it's html views. These views are hosted on our servers, which is divided into a production environment and an staging environment. I've set up the staging environment using Akamai so that all incoming request musts pass along a request header in order for the request to get accepted.

The issue:
Currently, I've created a subclass of WKWebView which overrides the loadRequest method, which looks something like this:

override func loadRequest(request: NSURLRequest) -> WKNavigation? {
    guard let mutableRequest = request.mutableCopy() as? NSMutableURLRequest else {
        return super.loadRequest(request)
    }

    if let url = request.URL, host = url.host {
        if (host == "staging.example.com") {
            mutableRequest.setValue("secret-value", forHTTPHeaderField: "secret-header")
        }
    }


    return super.loadRequest(mutableRequest)
}

This catches the initial html request, which works as expected. However, since this page in it's turn loads both images, stylesheets and scripts from the same server, these does not go through the loadRequest method and gets denied because their request lack this required request header.

Requirements:
It has got to work with WKWebView on iOS 8+.

Foison answered 16/9, 2016 at 19:8 Comment(0)
E
4

It is impossible with current API - there is no point where you can handle all requests that made by WKWebView. You can use UIWebView + custom url protocol (WKWebView doesn't support it) and add your header to all requests for certain server as an alternative.

Epigeal answered 17/9, 2016 at 21:3 Comment(1)
Bummer. Thank you for answering!Foison
B
1

For anyone coming onto this in the future, it is possible:

 extension SomeObjectThatIsADelegate: WKNavigationDelegate {

 // Intercept all requests and insert the necessary headers
 func webView(
     _ webView: WKWebView,
     decidePolicyFor navigationAction: WKNavigationAction,
     decisionHandler: @escaping (WKNavigationActionPolicy) -> Void
 ) {
     let headerName = "Header-Name"
     let expectedHeaderValue = "header_value"

     let headers = navigationAction.request.allHTTPHeaderFields ?? [:]
     let isMatched = headers.contains { $0.key == headerName && $0.value == expectedHeaderValue }

     if isMatched {
         decisionHandler(.allow)
     } else {
         // Cancel and re-run the request with our header inserted
         decisionHandler(.cancel)

         var requestWithDeviceType = navigationAction.request
         var headers = requestWithDeviceType.allHTTPHeaderFields ?? [:]
         headers[headerName] = expectedHeaderValue
         requestWithDeviceType.allHTTPHeaderFields = headers
         webView.load(requestWithDeviceType)
     }
 }
Baalbek answered 22/9, 2023 at 16:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.