如何为WKWebView发送的请求设置自定义HTTP头

15

我已经建立了一个包含WKWebView的应用程序,该Web视图加载的网站支持多种语言。我如何更改WKWebView中的Accept-Language标头,或者更改其他HTTP标头呢?


1
这有点类似于https://dev59.com/o14b5IYBdhLWcg3wiSPV#37474812的重复。 请查看我在那个问题上的答案,它会起作用。我已经测试了Accept-Language并且可以被覆盖。 - Gabriel Cartier
2
该解决方案仅适用于初始请求,而不适用于子资源。 - mservidio
这可以通过拦截HTTP请求来实现,但这可能就像杀一只苍蝇用加农炮。 - Alex Cohn
3个回答

6
我已经使它工作,但只有GET请求将具有自定义标头。正如jbelkins在链接中回答Gabriel Cartiers对您的问题的评论中所说,您将不得不操纵请求并重新加载它。
我已经使其适用于此类GET请求:
(这是在Xamarin 0> C#中完成的,但我认为你会理解的)
我已创建了一个私有字段。
private bool _headerIsSet

我在代理方法中每次发出请求时都会检查:

[Foundation.Export("webView:decidePolicyForNavigationAction:decisionHandler:")]
    public void DecidePolicy(WKWebView webView, WKNavigationAction navigationAction, Action<WKNavigationActionPolicy> decisionHandler)
    {
        var request = navigationAction.Request;
        // check if the header is set and if not, create a muteable copy of the original request
        if (!_headerIsSet && request is NSMuteableUrlRequest muteableRequest);              
        {
            // define your custom header name and value
            var keys = new object[] {headerKeyString};
            var values = new object[] {headerValueString};
            var headerDict = NSDictionary.FromObjectsAndKeys(values, keys);
            // set the headers of the new request to the created dict
            muteableRequest.Headers = headerDict;
            _headerIsSet = true;
            // attempt to load the newly created request
            webView.LoadRequest(muteableRequest);
            // abort the old one
            decisionHandler(WKNavigationActionPolicy.Cancel);
            // exit this whole method
            return;
        }
        else
        {
            _headerIsSet = false;                
            decisionHandler(WKNavigationActionPolicy.Allow);
        }
    }

如我所说,这仅适用于GET请求。不知何故,POST请求不包含原始请求的主体数据(request.Body和request.BodyStream为空),因此可变请求(它是原始请求的可变副本)将不包含原始请求的主体数据。
我希望这可以帮助您或其他人解决同样的问题。 编辑:为了满足您的需求,请将"Accept-Language"设置为键。

这个解决方法除了被限制在GET之外,还有另一个问题。它还假设将要拦截的请求会替换WebView的整个内容。这并不总是正确的:如果这样的次要请求旨在更改页面上的某些元素,例如显示的图像,则结果将远非预期。 - Alex Cohn
@AlexCohn 我不确定,你是否遇到了这样的行为?只有在发生导航操作时(例如页面更改),才应调用DecidePolicy。 - DerDingens
这正是问题所在:ajax请求、图像请求等不受此方法处理。 - Alex Cohn
哦,好的,我误解了你的意思,确实不会这样处理。 - DerDingens
这可以通过拦截HTTP请求来实现,但这可能有点大材小用。 - Alex Cohn

4

只需在URL请求中像下面这样设置所需的语言ISO 639-1代码,就可以从服务器端获取用户首选或本地化语言响应。

Swift 4及以上版本

var request = URLRequest(url: URL(string: "YourUrlStr"))
request.setValue("en", forHTTPHeaderField: "Accept-Language")
wkWebView.load(request)

Objective-C

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:YourUrlStr]];
[request setValue:@"en" forHTTPHeaderField:@"Accept-Language"];
[wkWebView loadRequest:urlRequest];

0
  1. WKWebView支持开箱即用的本地化。您不需要设置“Accept-Language”头字段。

  2. 如果出于某种原因您需要这样做,以下是实现方法。

创建一个'URLRequest',使用所需网站初始化URL的实例。

var request = URLRequest(url: url)

维护所需区域设置的映射,并相应地设置“Accept-Language”头字段。
request.setValue("de-de", forHTTPHeaderField: "Accept-Language")

使用'WKWebView'的实例加载'URLRequest'。
webview.load(request)
  • 同样地,任何报头字段都可以被更改

  • 网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接