Ändern Sie den Benutzeragenten in UIWebView

70

Ich muss in der Lage sein, den UserAgent für eine eingebettete UIWebView anzupassen. (Ich möchte beispielsweise, dass der Server anders reagiert, wenn beispielsweise ein Benutzer eine Version der App im Vergleich zu einer anderen verwendet.)

Ist es möglich, den UserAgent im vorhandenen UIWebView-Steuerelement so anzupassen, wie es beispielsweise für einen eingebetteten IE-Browser in einer Windows-App ist?

Cœur
quelle

Antworten:

95

Modern Swift

Hier ist ein Vorschlag für Swift 3+ -Projekte von StackOverflow-Benutzern PassKit und Kheldar:

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

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

Frühere Objective-C-Antwort

Bei Änderungen an iOS 5 empfehle ich den folgenden Ansatz, der ursprünglich aus dieser StackOverflow-Frage stammt: UIWebView iOS5 ändert den Benutzeragenten, wie in einer Antwort unten angegeben. In Kommentaren auf dieser Seite scheint es auch in 4.3 und früher zu funktionieren.

Ändern Sie den Standardwert "UserAgent", indem Sie diesen Code beim Start Ihrer App einmal ausführen:

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

Weitere Informationen finden Sie in den vorherigen Änderungen in diesem Beitrag, wenn Sie Methoden benötigen, die in iOS-Versionen vor 4.3 / 5.0 funktionieren. Beachten Sie, dass aufgrund der umfangreichen Änderungen die folgenden Kommentare / anderen Antworten auf dieser Seite möglicherweise keinen Sinn ergeben. Immerhin ist dies eine vier Jahre alte Frage. ;-);

Louis St-Amour
quelle
Ein Nachteil dieses Ansatzes: Wenn Ihre WebView benutzerdefinierte URLs enthält (Anwendung: //), schlagen diese fehl, da Sie immer JA zurückgeben.
jpoz
6
@stigi versuchen, den Schlüssel von @ "User_Agent" in @ "User-Agent" zu ändern. Das hat bei mir funktioniert.
William Niu
Weiß jemand, wie man es durch AJAX-Aufrufe beibehält?
Felipe Sabino
1
@nmr Dies war in 3.x Tagen zurück. Siehe mein "2012 Update" oben im Beitrag. Und nein, sorry, ich kann nicht sagen, warum es damals notwendig war. Es ist möglich, dass eine andere Ebene im TCP-Stapel Header mit Unterstrichen in Header mit Bindestrichen konvertiert. Ich kann nur sagen, dass sie dieses Verhalten inzwischen behoben haben, sodass ich mir darüber keine Sorgen machen würde.
Louis St-Amour
1
Könnte dies zunächst in der Steuerung für die Webansicht erfolgen? Möchten Sie zuerst die URL überprüfen und auf dieser Grundlage dies aufrufen [[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];? Grundsätzlich habe ich es schon versucht aber nicht geklappt. Ich möchte nur wissen, ob dies überhaupt möglich ist, da Sie dies zunächst beim Start vorschlagen.
Pedroinpeace
19

Ich hatte auch dieses Problem und versuchte alle Methoden. Ich habe festgestellt, dass nur diese Methode funktioniert (iOS 5.x): UIWebView iOS5 ändert den Benutzeragenten

Das Prinzip besteht darin, den Benutzeragenten dauerhaft in den Benutzereinstellungen festzulegen. Das funktioniert; Webview sendet den angegebenen Header. Nur zwei Codezeilen:

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

Setzen Sie User-Agent oder User_Agent in der veränderlichen Anforderung oder überschreiben Sie den setValue in der NSHttpRequest durch Swizzling. Ich habe das alles versucht und die Ergebnisse mit wireshark gesteuert, und nichts davon scheint zu funktionieren, da Webview immer noch den Wert des Benutzeragenten verwendet von den Standardeinstellungen des Benutzers, unabhängig davon, was Sie in der NSHttpRequest festlegen möchten.

winitzki
quelle
2
Nur das hat bei mir funktioniert! Sie können jetzt eine kürzere Version verwenden: [[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"UserAgent": @"custom agent" }];
Yariv Nissim
18

Es sollte mit einer NSMutableURLRequest funktionieren, wie Kuso geschrieben hat.

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

Sie müssen NSURLConnection verwenden, um die Antwortdaten abzurufen. Stellen Sie die Antwortdaten auf Ihre UIWebView ein und die WebView sollte Folgendes rendern:

[webView loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL];
Dshutsi
quelle
Wie würde die Zeichenfolge eines Benutzeragenten für eine Safari auf einem Mac aussehen?
AceN
12

Sehr einfach in Swift. Fügen Sie einfach Folgendes in Ihren App-Delegaten ein.

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

Wenn Sie an die vorhandene Agentenzeichenfolge anhängen möchten, gehen Sie wie folgt vor:

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

Hinweis: Möglicherweise müssen Sie die App deinstallieren und neu installieren, um ein Anhängen an die vorhandene Agentenzeichenfolge zu vermeiden.

PassKit
quelle
Vielen Dank. Viel Zeit gespart!
KD.
Vielen Dank an @Kheldar für das Update für Swift 3. Für frühere Swift-Versionen überprüfen Sie den Bearbeitungsverlauf.
PassKit
6

Das Hinzufügen eines Header-Felds zum NSURLRequest-Argument in shouldStartLoadWithRequest scheint zu funktionieren, da die Anforderung auf setValue: ForHTTPHeaderField reagiert - dies ist jedoch nicht der Fall funktioniert - die Anforderung wird ohne den Header gesendet.

Daher habe ich diese Problemumgehung in shouldStartLoadWithRequest verwendet, bei der die angegebene Anforderung nur in eine neue veränderbare Anforderung kopiert und erneut geladen wird. Dies ändert tatsächlich den Header, der gesendet wird.

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

Leider erlaubt dies immer noch nicht das Überschreiben des http-Headers des Benutzeragenten, der anscheinend von Apple überschrieben wird. Ich denke, um es zu überschreiben, müssten Sie eine NSURLConnection selbst verwalten.

Danra
quelle
6

Die Verwendung von @ "User_Agent" bewirkt lediglich, dass ein benutzerdefinierter Header in der GET-Anforderung angezeigt wird.

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

Das Obige erscheint im sezierten HTTP-Paket und bestätigt im Wesentlichen, was Sfjava aus diesem Forum zitiert hat. Es ist interessant festzustellen, dass "User-Agent" in "User_agent" umgewandelt wird.

dodeskjeggen
quelle
6

Wenn ich alles so nehme, wurde es für mich gelöst:

- (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];
}

Vielen Dank an alle.

Michael Robinson
quelle
5

Indem Sie die Antwort von Louis St-Amour und die NSUserDefaults+UnRegisterDefaultsKategorie aus dieser Frage / Antwort zusammenfassen , können Sie die folgenden Methoden verwenden, um das Spoofing von Benutzeragenten jederzeit zu starten und zu stoppen, während Ihre App ausgeführt wird:

#define kUserAgentKey @"UserAgent"

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

- (void)stopSpoofingUserAgent {
    [[NSUserDefaults standardUserDefaults] unregisterDefaultForKey:kUserAgentKey];
}
EthanB
quelle
1
getestet in iOS7 auf iPhone 5 Gerät und es funktioniert, funktioniert nicht auf Simulator, aber das spielt keine Rolle. Danke für die Information.
New2ObjectiveC
startSpoofingUserAgent funktioniert für mich, jedoch ist unregisterDefaultForKey kein gültiger Befehl. Die einzige Möglichkeit, dies zum Laufen zu bringen, bestand darin, ein registerDefaults mit dem ursprünglichen Wert zu erstellen, um es zurückzusetzen. -rrh
Richie Hyatt
unregisterDefaultForKey:wird hier implementiert: stackoverflow.com/a/18109860/1580288 (wie in der Antwort angegeben).
EthanB
4

Diese Lösung scheint als ein ziemlich kluger Weg gesehen worden zu sein, dies zu tun

Ändern der Header für UIwebkit-http-Anfragen

Es verwendet Method Swizzling und Sie können mehr darüber auf der Website erfahren CocoaDev-Seite erfahren

Schau es dir an!

Öffnen Sie SEO
quelle
2
Seit iOS 5 verwendet iOS die öffentliche API nicht mehr zum Erstellen seiner NSURLRequest-Objekte, sodass die Swizzling-Methode unter iOS 5 nicht mehr funktioniert.
Mike Keskinov
2

Ich stand vor der gleichen Frage. Ich möchte dem Benutzeragenten einige Informationen hinzufügen und muss auch den ursprünglichen Benutzeragenten von Webview beibehalten. Ich habe es mit dem folgenden Code gelöst:

    //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];

Verwenden Sie es, bevor Sie die Webansicht instanziieren.

Shannon Chou
quelle
1

Versuchen Sie dies in 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];

}
Aitul
quelle
1

Das einzige Problem, das ich gefunden habe, war, nur den Benutzeragenten zu ändern

- (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];
}
Sanjeev Sharma
quelle
0

Gehen Sie wie folgt vor, um dem aktuellen UserAgent-Wert nur einen benutzerdefinierten Inhalt hinzuzufügen:

1 - Rufen Sie den Benutzeragentenwert aus einer NEUEN WEBVIEW ab

2 - Fügen Sie den benutzerdefinierten Inhalt hinzu

3 - Speichern Sie den neuen Wert in einem Wörterbuch mit dem Schlüssel UserAgent

4 - Speichern Sie das Wörterbuch in standardUserDefaults.

Siehe das folgende Beispiel:

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];
Doug
quelle
0

Apple wird in Kürze keine Apps mehr mit UIWebView akzeptieren. Im Folgenden erfahren Sie, wie Sie den Benutzeragenten in WKWebView ändern können.

let config = WKWebViewConfiguration()

config.applicationNameForUserAgent = "My iOS app"

webView = WKWebView(frame: <the frame you need>, configuration: config)
DIE VERWENDUNG
quelle