我有一个业务需要能够为嵌入式 UIWebView 自定义 UserAgent。(例如,如果用户使用的是应用程序的一个版本而不是另一个版本,我希望服务器做出不同的响应。)
是否可以像 Windows 应用程序中的嵌入式 IE 浏览器那样自定义现有 UIWebView 控件中的 UserAgent?
我有一个业务需要能够为嵌入式 UIWebView 自定义 UserAgent。(例如,如果用户使用的是应用程序的一个版本而不是另一个版本,我希望服务器做出不同的响应。)
是否可以像 Windows 应用程序中的嵌入式 IE 浏览器那样自定义现有 UIWebView 控件中的 UserAgent?
以下是 StackOverflow 用户 PassKit 和 Kheldar 对 Swift 3+ 项目的建议:
UserDefaults.standard.register(defaults: ["UserAgent" : "Custom Agent"])
来源:https ://stackoverflow.com/a/27330998/128579
随着 iOS 5 的变化,我推荐以下方法,最初来自这个 StackOverflow 问题:UIWebView iOS5 changed user-agent as pointed in an answer below。在该页面的评论中,它似乎也适用于 4.3 及更早版本。
通过在您的应用启动时运行此代码一次来更改“UserAgent”默认值:
NSDictionary *dictionary = @{@"UserAgent": @"Your user agent"}; [[NSUserDefaults standardUserDefaults] registerDefaults:dictionary]; [[NSUserDefaults standardUserDefaults] synchronize];
如果您需要在 4.3/5.0 之前的 iOS 版本中工作的方法,请参阅这篇文章的先前编辑。请注意,由于进行了广泛的编辑,此页面上的以下评论/其他答案可能没有意义。毕竟,这是一个四年前的问题。;-)
我也遇到了这个问题,各种方法都试过了。我发现只有这种方法有效(iOS 5.x): UIWebView iOS5 changed user-agent
原理是在用户设置中永久设置用户代理。这行得通;Webview 发送给定的标头。只需两行代码:
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"Mozilla/Whatever version 913.6.beta", @"UserAgent", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];
在可变请求中设置 User-Agent 或 User_Agent,或者通过 swizzling 覆盖 NSHttpRequest 中的 setValue,-我尝试了所有这些并使用 wireshark 控制了结果,但这些似乎都不起作用,因为 Webview 仍然使用用户代理值从用户默认值开始,无论您尝试在 NSHttpRequest 中设置什么。
它应该与 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.
您必须使用 NSURLConnection 来获取 responseData。将 responseData 设置为您的 UIWebView 并且 webView 应该呈现:
[webView loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL];
在 Swift 中非常简单。只需将以下内容放入您的 App Delegate 中。
UserDefaults.standard.register(defaults: ["UserAgent" : "Custom Agent"])
如果要附加到现有代理字符串,则:
let userAgent = UIWebView().stringByEvaluatingJavaScript(from: "navigator.userAgent")! + " Custom Agent"
UserDefaults.standard.register(defaults: ["UserAgent" : userAgent])
注意:您可能需要卸载并重新安装应用程序以避免附加到现有代理字符串。
采取一切这就是它为我解决的方法:
- (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];
}
感谢大家。
使用 @"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
以上是剖析的 HTTP 数据包中出现的内容,基本上证实了 Sfjava 从该论坛引用的内容。有趣的是,“User-Agent”变成了“User_agent”。
实际上,将任何标头字段添加到 shouldStartLoadWithRequest 中的 NSURLRequest 参数 似乎有效,因为请求响应 setValue:ForHTTPHeaderField - 但它实际上不起作用- 请求在没有标头的情况下发出。
所以我在 shouldStartLoadWithRequest 中使用了这个解决方法,它只是将给定的请求复制到一个新的可变请求中,然后重新加载它。这实际上会修改发送出去的标头。
if ( [request valueForHTTPHeaderField:@"MyUserAgent"] == nil )
{
NSMutableURLRequest *modRequest = [request mutableCopyWithZone:NULL];
[modRequest setValue:@"myagent" forHTTPHeaderField:@"MyUserAgent"];
[webViewArgument loadRequest:modRequest];
return NO;
}
不幸的是,这仍然不允许覆盖用户代理 http 标头,该标头显然已被 Apple 覆盖。我想要覆盖它,您必须自己管理 NSURLConnection 。
通过汇集Louis St-Amour 的答案和来自这个问题/答案NSUserDefaults+UnRegisterDefaults
的类别,您可以使用以下方法在您的应用程序运行时随时启动和停止用户代理欺骗:
#define kUserAgentKey @"UserAgent"
- (void)startSpoofingUserAgent:(NSString *)userAgent {
[[NSUserDefaults standardUserDefaults] registerDefaults:@{ kUserAgentKey : userAgent }];
}
- (void)stopSpoofingUserAgent {
[[NSUserDefaults standardUserDefaults] unregisterDefaultForKey:kUserAgentKey];
}
这个解决方案似乎被视为一种非常聪明的方法
更改-the-headers-for-uiwebkit-http-requests
它使用 Method Swizzling,您可以在CocoaDev 页面上了解更多信息
给它看看!
我面临同样的问题。我想向用户代理添加一些信息,还需要保留 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];
在实例化 webview 之前使用它。
Try this in the AppDelegate.m
+ (void)initialize
{
// Set user agent (the only problem is that we can’t modify the User-Agent later in the program)
// iOS 5.1
NSDictionary *dictionnary = [[NSDictionary alloc] initWithObjectsAndKeys:@”Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B176 Safari/7534.48.3”, @”UserAgent”, nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionnary];
}
我发现的唯一问题是仅更改用户代理
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSDictionary *dictionary = [NSDictionary
dictionaryWithObjectsAndKeys:
@"Mozilla/5.0 (iPod; U; CPU iPhone OS 4_3_3 like Mac OS X; ja-jp) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5",
@"UserAgent", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];
}
Apple 将很快停止接受带有 UIWebView 的应用程序。在下面查找如何更改 WKWebView 中的用户代理。
let config = WKWebViewConfiguration()
config.applicationNameForUserAgent = "My iOS app"
webView = WKWebView(frame: <the frame you need>, configuration: config)
要将自定义内容添加到当前 UserAgent 值,请执行以下操作:
1 - 从新的 WEBVIEW 获取用户代理值
2 - 将自定义内容附加到它
3 - 使用键 UserAgent 将新值保存在字典中
4 - 将字典保存在标准用户默认值中。
请参见下面的示例:
NSString *userAgentP1 = [[[UIWebView alloc] init] stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
NSString *userAgentP2 = @"My_custom_value";
NSString *userAgent = [NSString stringWithFormat:@"%@ %@", userAgentP1, userAgentP2];
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:userAgent, @"UserAgent", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];