ios 在 UIWebView 中更改用户代理

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/478387/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 15:35:13  来源:igfitidea点击:

Change User Agent in UIWebView

iosiphonecocoa-touchuiwebview

提问by Louis St-Amour

I have a business need to be able to customize the UserAgent for an embedded UIWebView. (For instance, I'd like the server to respond differently if, say, a user is using one version of the app versus another.)

我的业务需要能够为嵌入式 UIWebView 自定义 UserAgent。(例如,如果用户使用的是应用程序的一个版本而不是另一个版本,我希望服务器做出不同的响应。)

Is it possible to customize the UserAgent in the existing UIWebView control the way it is, say, for an embedded IE browser in a Windows app?

是否可以像 Windows 应用程序中的嵌入式 IE 浏览器那样自定义现有 UIWebView 控件中的 UserAgent?

回答by Louis St-Amour

Modern Swift

现代斯威夫特

Here's a suggestion for Swift 3+ projects from StackOverflow users PassKit and Kheldar:

这是 StackOverflow 用户 PassKit 和 Kheldar 对 Swift 3+ 项目的建议:

UserDefaults.standard.register(defaults: ["UserAgent" : "Custom Agent"])

Source: https://stackoverflow.com/a/27330998/128579

来源:https: //stackoverflow.com/a/27330998/128579

Earlier Objective-C Answer

较早的 Objective-C 答案

With iOS 5 changes, I recommend the following approach, originally from this StackOverflow question: UIWebView iOS5 changing user-agentas pointed out in an answer below. In comments on that page, it appears to work in 4.3 and earlier also.

随着 iOS 5 的变化,我推荐以下方法,最初来自这个 StackOverflow 问题:UIWebView iOS5 更改用户代理,如下面的答案中所指出的。在该页面的评论中,它似乎也适用于 4.3 及更早版本。

Change the "UserAgent" default value by running this code once when your app starts:

NSDictionary *dictionary = @{@"UserAgent": @"Your user agent"};
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];
[[NSUserDefaults standardUserDefaults] synchronize];

通过在您的应用程序启动时运行一次此代码来更改“UserAgent”默认值:

NSDictionary *dictionary = @{@"UserAgent": @"Your user agent"};
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];
[[NSUserDefaults standardUserDefaults] synchronize];

See previous edits on this post if you need methods that work in versions of iOS before 4.3/5.0. Note that because of the extensive edits, the following comments / other answers on this page may not make sense. This is a four year old question, after all. ;-)

如果您需要在 4.3/5.0 之前的 iOS 版本中使用的方法,请参阅此帖子的先前编辑。请注意,由于进行了大量编辑,此页面上的以下评论/其他答案可能没有意义。毕竟,这是一个四年前的问题。;-)

回答by winitzki

I had this problem too, and tried all methods. I found that only this method works (iOS 5.x): UIWebView iOS5 changing user-agent

我也有这个问题,各种方法都试过了。我发现只有这种方法有效(iOS 5.x): UIWebView iOS5 更改用户代理

The principle is to set the user agent permanently in the user settings. This works; Webview sends the given header. Just two lines of code:

原理是在用户设置中永久设置用户代理。这有效; Webview 发送给定的标头。只需两行代码:

NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"Mozilla/Whatever version 913.6.beta", @"UserAgent", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];

Setting User-Agent, or User_Agent in the mutable request, or overriding the setValue in the NSHttpRequest by swizzling, - I tried all that and controlled the results with wireshark, and none of that seems to work, because Webview still uses the user agent value from the user defaults, no matter what you try to set in the NSHttpRequest.

在可变请求中设置 User-Agent 或 User_Agent,或通过 swizzling 覆盖 NSHttpRequest 中的 setValue, - 我尝试了所有这些并使用wireshark 控制结果,但这些似乎都不起作用,因为 Webview 仍然使用用户代理值来自用户默认值,无论您尝试在 NSHttpRequest 中设置什么。

回答by Dshutsi

It should work with an NSMutableURLRequest as Kuso has written.

它应该与 Kuso 编写的 NSMutableURLRequest 一起使用。

NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: @"http://www.google.com/"]];
[urlRequest setValue: @"iPhone" forHTTPHeaderField: @"User-Agent"]; // Or any other User-Agent value.

You'll have to use NSURLConnection to get the responseData. Set the responseData to your UIWebView and the webView should render:

您必须使用 NSURLConnection 来获取 responseData。将 responseData 设置为您的 UIWebView 并且 webView 应该呈现:

[webView loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL];

回答by PassKit

Very simple in Swift. Just place the following into your App Delegate.

在 Swift 中非常简单。只需将以下内容放入您的 App Delegate。

UserDefaults.standard.register(defaults: ["UserAgent" : "Custom Agent"])

If you want to append to the existing agent string then:

如果要附加到现有代理字符串,则:

let userAgent = UIWebView().stringByEvaluatingJavaScript(from: "navigator.userAgent")! + " Custom Agent"
UserDefaults.standard.register(defaults: ["UserAgent" : userAgent])

Note: You may will need to uninstall and reinstall the App to avoid appending to the existing agent string.

注意:您可能需要卸载并重新安装应用程序以避免附加到现有代理字符串。

回答by Danra

Actually adding any header field to the NSURLRequest argument in shouldStartLoadWithRequest seemsto work, because the request responds to setValue:ForHTTPHeaderField - but it doesn'tactually work - the request is sent out without the header.

其实添加任何头字段中shouldStartLoadWithRequest中的NSURLRequest说法 似乎工作,因为这个请求给setValue:ForHTTPHeaderField -但它并没有真正的工作-在请求被发送出去没有头。

So I used this workaround in shouldStartLoadWithRequest which just copies the given request to a new mutable request, and re-loads it. This does in fact modify the header which is sent out.

所以我在 shouldStartLoadWithRequest 中使用了这个解决方法,它只是将给定的请求复制到一个新的可变请求,然后重新加载它。这实际上修改了发送出去的头。

if ( [request valueForHTTPHeaderField:@"MyUserAgent"] == nil )
{
    NSMutableURLRequest *modRequest = [request mutableCopyWithZone:NULL];
    [modRequest setValue:@"myagent" forHTTPHeaderField:@"MyUserAgent"];
    [webViewArgument loadRequest:modRequest];
    return NO;
}

Unfortunately, this still doesn't allow overriding the user-agent http header, which is apparently overwritten by Apple. I guess for overriding it you would have to manage a NSURLConnection by yourself.

不幸的是,这仍然不允许覆盖 user-agent http 标头,它显然被 Apple 覆盖了。我想要覆盖它,您必须自己管理 NSURLConnection 。

回答by Michael Robinson

Taking everything this is how it was solved for me:

把这一切都是为我解决的方式:

- (void)viewDidLoad {
    NSURL *url = [NSURL URLWithString: @"http://www.amazon.com"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request setValue:@"Foobar/1.0" forHTTPHeaderField:@"User-Agent"];
    [webView loadRequest:request];
}

Thanks Everyone.

谢谢大家。

回答by dodeskjeggen

Using @"User_Agent" simply causes a custom header to appear in the GET request.

使用@"User_Agent" 只会导致自定义标头出现在 GET 请求中。

User_agent: Foobar/1.0\r\n
User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_1_2 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Mobile/7D11\r\n

User_agent: Foobar/1.0\r\n
User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_1_2 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Mobile/7D11\r\n

The above is what appears in the dissected HTTP packet, essentially confirming what Sfjava was quoting from that forum. It's interesting to note that "User-Agent" gets turned into "User_agent."

以上是在剖析的 HTTP 数据包中出现的内容,基本上证实了 Sfjava 从该论坛引用的内容。有趣的是,“User-Agent”变成了“User_agent”。

回答by EthanB

By pooling the answer by Louis St-Amourand the NSUserDefaults+UnRegisterDefaultscategory from this question/answer, you can use the following methods to start and stop user-agent spoofing at any time while your app is running:

通过汇集Louis St-Amour 的答案此问题/答案中NSUserDefaults+UnRegisterDefaults类别,您可以使用以下方法在您的应用程序运行时随时启动和停止用户代理欺骗:

#define kUserAgentKey @"UserAgent"

- (void)startSpoofingUserAgent:(NSString *)userAgent {
    [[NSUserDefaults standardUserDefaults] registerDefaults:@{ kUserAgentKey : userAgent }];
}

- (void)stopSpoofingUserAgent {
    [[NSUserDefaults standardUserDefaults] unregisterDefaultForKey:kUserAgentKey];
}

回答by Open SEO

This solution seems to have been seen as a pretty clever way to do it

这个解决方案似乎被视为一种非常聪明的方法

changing-the-headers-for-uiwebkit-http-requests

更改标题为 uiwebkit-http-requests

It uses Method Swizzling and you can learn more about it on the CocoaDev page

它使用 Method Swizzling,您可以在CocoaDev 页面上了解更多信息

Give it a look !

看看吧!

回答by Shannon Chou

I faced the same question. I want to add some info to the user-agent, also need to keep the original user-agent of webview. I solved it by using the code below:

我面临同样的问题。我想向用户代理添加一些信息,还需要保留 webview 的原始用户代理。我使用下面的代码解决了它:

    //get the original user-agent of webview
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectZero];
NSString *oldAgent = [webView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
NSLog(@"old agent :%@", oldAgent);

//add my info to the new agent
NSString *newAgent = [oldAgent stringByAppendingString:@" Jiecao/2.4.7 ch_appstore"];
NSLog(@"new agent :%@", newAgent);

//regist the new agent
NSDictionary *dictionnary = [[NSDictionary alloc] initWithObjectsAndKeys:newAgent, @"UserAgent", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionnary];

Use it before you instancing webview.

在实例化 webview 之前使用它。