Sonderzeichen an URL übergeben

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Sonderzeichen an URL übergeben

    Ich quäle mich immer noch mit dieser Webseite dailygammon.com rum :rolleyes:

    ich hab ja schon sehr viel zum laufen bekommen, aber der Chat kostet mich die letzten Nerven.

    ich denk mal positiv und gehe davon aus, dass ich mich nur irgendwo verrannt habe. <X

    Ich habe einen UITextView. Da gibt der Anwender seine eloquenten Texte in beliebiger Sprache ein.
    Diesen Text und ein paar andere Informationen baue ich dann zu einer URL zusammen.
    Es funktioniert auch alle wunderbar, nur bei "Sonderzeichen" kommt auf der anderen Seite "seltsame" Zeichen im Chat an.
    Beispiel:
    Ich gebe im Chat als Test ein: "Über can't" den ich dann versuche folgendermaßen für die URL vorzubereiten:

    C-Quellcode

    1. NSString *escapedString = [self.playerChat.text stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
    2. matchLink = [NSString stringWithFormat:@"%@?submit=Next%%20Game&commit=1%@&chat=%@",
    3. [self.actionDict objectForKey:@"action"],
    4. checkbox,
    5. escapedString2];
    6. NSURL *urlMatch = [NSURL URLWithString:[NSString stringWithFormat:@"http://dailygammon.com%@",matchLink]];
    7. NSData *matchHtmlData = [NSData dataWithContentsOfURL:urlMatch];
    die URL sieht dann so aus: /bg/move/4001894/292?submit=Next%20Game&commit=1&chat=%C3%9Cber+can%E2%80%98t

    und auf der Webseite kommt dann so etwas an "Über can‘t"


    hat jemand einen Tip für mich?

    Hatten wir zwar schon drüber gesprochen:
    Nein, ich habe keine Ahnung welchen char-set die Website eingestellt hat. Wenn man sich den Quelltext von dailygammon.com anschaut, ist da auch nichts zu erkennen.
    Nein, der Betreiber der Seite gibt keinerlei Auskünfte. Er freut sich aber über die App, hat nur gleich klar gestellt, dass er keine Zeit hat sich um irgendwas zu kümmern.
    Ich habe auch keine Loesung, aber ich bewundere das Problem!
    _____________________________________________________


  • Ich kann nur dazu sagen, dass dein Encoding falsch ist.

    %E2 steht für das a mit dem dach drauf und nicht für ein Apostroph

    w3schools.com/tags/ref_urlencode.asp

    Also muss du wohl irgendwas beim Encoding anders einstellen, damit das richtige Zeichen raus kommt was hier dann wohl eher %27 wäre

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Anstelle von URLHostAllowedCharacterSet solltest Du lieber URLQueryAllowedCharacterSet verwenden. Du möchtest ja den Query Teil der URL percent encoden. Es wäre auch besser die komplette Query zusammen zu bauen und dann stringByAddingPercentEncodingWithAllowedCharacters: zu verwenden.

    Dies dürfte allerdings nichts an dem Text Encoding Problem ändern.

    Als CharacterSet könntest Du auch mal alphanumericCharacterSet ausprobieren oder die URL mal per NSURLComponents und NSURLQueryItem zusammen bauen.
  • MCDan schrieb:

    Anstelle von URLHostAllowedCharacterSet solltest Du lieber URLQueryAllowedCharacterSet verwenden.
    Da kommt exakt das gleiche raus wie bei URLHostAllowedCharacterSet

    Quellcode

    1. NSString *escapedString = [self.playerChat.text
    2. stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
    3. NSString *escapedString1 = [self.playerChat.text
    4. stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    Ich habe auch keine Loesung, aber ich bewundere das Problem!
    _____________________________________________________


  • hape42 schrieb:

    MCDan schrieb:

    Anstelle von URLHostAllowedCharacterSet solltest Du lieber URLQueryAllowedCharacterSet verwenden.
    Da kommt exakt das gleiche raus wie bei URLHostAllowedCharacterSe

    Quellcode

    1. NSString *escapedString = [self.playerChat.text
    2. stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
    3. NSString *escapedString1 = [self.playerChat.text
    4. stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    Evtl. gibt es nur Unterschiede, wenn ein & in der Query auftaucht. Habe dies allerdings noch nicht genau untersucht.

    Dann probiere doch mal alphanumericCharacterSet als CharacterSet oder baue die URL mal per NSURLComponents und NSURLQueryItem zusammen.
  • MCDan schrieb:

    Dann probiere doch mal alphanumericCharacterSet als CharacterSet oder baue die URL mal per NSURLComponents und NSURLQueryItem zusammen.

    Quellcode

    1. NSURLComponents *components = [[NSURLComponents alloc] init];
    2. components.scheme = @"http";
    3. components.host = @"www.dailygammon.com";
    4. components.path = [self.actionDict objectForKey:@"action"];
    5. components.query = [NSString stringWithFormat:@"submit=Next Game&commit=1%@&chat=%@",
    6. checkbox,
    7. self.playerChat.text];
    8. NSURL *url = components.URL;

    Printing description of url:

    Quellcode

    1. http://www.dailygammon.com/bg/move/4001893/167?submit=Next%20Game&commit=1&chat=%C3%9Cber%20can%E2%80%98t

    Gleiches Resultat ?(
    Ich habe auch keine Loesung, aber ich bewundere das Problem!
    _____________________________________________________


    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von hape42 ()

  • MCDan schrieb:

    Dann probiere doch mal alphanumericCharacterSet als CharacterSet

    C-Quellcode

    1. NSString *escapedString3 = [self.playerChat.text stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet alphanumericCharacterSet]];

    gleiches Resultat :

    Quellcode

    1. %C3%9Cber%20can%E2%80%98t
    Ich habe auch keine Loesung, aber ich bewundere das Problem!
    _____________________________________________________


  • Au ja, ich rate auch einmal mit :D

    Ich tippe ja darauf, dass das Problem nicht das String-Encoding der URL ist, sondern der Response vom Server, der (wahrscheinlich) nur als "text/html" ausliefert ... zumindest sah das eben nach einem curl -X HEAD -i http://www.dailygammon.com/ so aus:

    Quellcode

    1. HTTP/1.1 200 OK
    2. Date: Wed, 20 Mar 2019 15:39:22 GMT
    3. Server: Apache/2.2.22 (Ubuntu)
    4. Last-Modified: Fri, 15 Apr 2011 02:11:32 GMT
    5. ETag: "7ea74-1b1-4a0eb8f88c2db"
    6. Accept-Ranges: bytes
    7. Content-Length: 433
    8. Vary: Accept-Encoding
    9. Content-Type: text/html
    10. X-Pad: avoid browser bug
    Ich würde einmal versuchen, den HTTP-Request nicht implizit per [NSData dataWithContentsOfURL:] abzusetzen, sondern mittels NSMutableURLRequest. Das erlaubt Dir dann, Parameter per setValue:forHTTPHeaderField: zu setzen. Mein Verdächtiger wäre hierbei ein Accept-Charset: utf-8, um dem Server mitzuteilen, dass Dein Programm UTF-8 verträgt...

    Schon im Voraus eine Entschuldigung wenn es nicht klappt, weil (1.) ich wirklich nur im Trüben fische und (2.) der Test ein wenig aufwendiger ist, da Du bisher keinen URLRequest nutzt.

    Grüße, Mattes

    Edit: Vielleicht kannst Du den Effekt ja auch erst "trocken" per curl testen ... je nachdem, was Du alles an Cookies, Session-ID etc. berücksichtigen musst.
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • hape42 schrieb:

    MCDan schrieb:

    Dann probiere doch mal alphanumericCharacterSet als CharacterSet oder baue die URL mal per NSURLComponents und NSURLQueryItem zusammen.

    Quellcode

    1. NSURLComponents *components = [[NSURLComponents alloc] init];
    2. components.scheme = @"http";
    3. components.host = @"www.dailygammon.com";
    4. components.path = [self.actionDict objectForKey:@"action"];
    5. components.query = [NSString stringWithFormat:@"submit=Next Game&commit=1%@&chat=%@",
    6. checkbox,
    7. self.playerChat.text];
    8. NSURL *url = components.URL;

    Printing description of url:

    Quellcode

    1. http://www.dailygammon.com/bg/move/4001893/167?submit=Next%20Game&commit=1&chat=%C3%9Cber%20can%E2%80%98t
    Gleiches Resultat ?(
    Mir ging es hier vorrangig um die Verwendung von NSURLQueryItem, damit NSURLComponents die Items in der URL entsprechend auflöst.

    Also in etwa so:

    C-Quellcode

    1. NSURLComponents *components = [[NSURLComponents alloc] init];
    2. components.scheme = @"http";
    3. components.host = @"www.dailygammon.com";
    4. components.path = @"/bg/move/4001893/167";
    5. NSURLQueryItem *item1 = [[NSURLQueryItem alloc] initWithName:@"submit" value:@"Next Game"];
    6. NSURLQueryItem *item2 = [[NSURLQueryItem alloc] initWithName:@"chat" value:@"Über can't"];
    7. components.queryItems = @[item1,item2];
    8. NSURL *url = components.URL;
    9. NSLog(@"url:%@",url);
    Aber auch damit sieht die URL dann wie gehabt aus "dailygammon.com/bg/move/400189…Game&chat=%C3%9Cber%20can't".


    Alternativ versuche es mal mit einem NSURLRequest z.B. etwa so:

    Quellcode

    1. #import <Foundation/Foundation.h>
    2. NSDictionary *headers = @{ @"cache-control": @"no-cache",
    3. @"content-type": @"application/x-www-form-urlencoded");
    4. NSMutableData *postData = [[NSMutableData alloc] initWithData:[@"submit=Next Game" dataUsingEncoding:NSUTF8StringEncoding]];
    5. [postData appendData:[@"&chat=Über can't" dataUsingEncoding:NSUTF8StringEncoding]];
    6. NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.dailygammon.com/bg/move/4001893/167"]
    7. cachePolicy:NSURLRequestUseProtocolCachePolicy
    8. timeoutInterval:10.0];
    9. [request setHTTPMethod:@"POST"];
    10. [request setAllHTTPHeaderFields:headers];
    11. [request setHTTPBody:postData];
    12. NSURLSession *session = [NSURLSession sharedSession];
    13. NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
    14. completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    15. if (error) {
    16. NSLog(@"%@", error);
    17. } else {
    18. NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
    19. NSLog(@"%@", httpResponse);
    20. }
    21. }];
    22. [dataTask resume];
    Alles anzeigen
  • hape42 schrieb:

    und auf der Webseite kommt dann so etwas an "Über can‘t"


    hat jemand einen Tip für mich?
    Für mich sieht das danach aus, dass du deinen Text UTF-8-Codiert hinschickst, der Server das auch so übernimmt. Wenn ich mir den html-Code von dailygammon.com anschaue, ist da kein meta-Tag enthalten, der eine Codierung angibt. Der Browser nimmt also die eingestellte Standardcodierung an, was offensichtlich IOS-Latin-1 ist.
    Wenn du nun mal deinen Browser sagst, er soll UTF-8 nehmen (Safari: Menü Darstellung->Textcodierung), dann wette ich, wird auch das angezeigt, was du hingeschickt hast.
  • Michael schrieb:

    MyMattes schrieb:

    Der „Browser“ ist in @hape42‘s Fall aber doch seine App
    Wo steht das? Oben hat er geschrieben:

    hape42 schrieb:

    und auf der Webseite kommt dann so etwas an "Über can‘t"

    MyMattes schrieb:

    im Safari funktioniert es.
    sagt wer?
    ich versuch das Wirrwarr mal ein wenig zu klären.

    dailygammon.com ist ein BackgammonServer der von "jemand der nicht ich bin" betrieben wird.
    Die HTML Seiten sind seit vielen Jahren unverändert und Stabil. Das Konzept dieses Servers ist älter als die modernen Smartphones & Tablets

    Ich habe mich getraut diesen HTML Code zu Parsen und damit ein optimales Spielerlebnis für iPads & iPhones zu ermöglichen. Das funktioniert auch alles bis auf den Nachrichtenaustausch via Chatfenster. Einfache Sprache funktioniert. Umlaute und zB Apostroph funktioniert nicht

    Wenn ich auf der Webseite im Chatfenster "Über can't" eingebe, kommt bei dem Mitspieler sowohl auf der Webseite als auch in meiner App alles richtig an.
    Gebe ich in meiner App im Chatfenster "Über can't" kommt der oben beschriebene Mist an.

    Ich werde heute mal den Vorschlag von MCDan und MyMattes umsetzen. Ich werde hier berichten.

    @Michael den Versuch mit IOS-Latin-1 werde ich auch heute mal versuchen umzusetzen. Muss mal noch googeln, wie ich das mache.
    Ich hoffe mal, dass ich aus dem Vorschlag MCDan einfach von NSUTF8StringEncoding auf IOS-Latin-1 umstellen kann :rolleyes:

    Es bleibt spannend ...
    Ich habe auch keine Loesung, aber ich bewundere das Problem!
    _____________________________________________________


    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von hape42 () aus folgendem Grund: Tippfehler

  • Zwischenergebnis:

    Der Vorschlag von MCDan & MyMattes bringt auch keine Verbesserung. zusätzlich hätte ich noch das Problem zu lösen dass ich die durch die übertragene URL erzeugte HTMLseite als return brauche. Darum kam ich überhaupt auf NSData *matchHtmlData = [NSData dataWithContentsOfURL:urlMatch];

    Aber Michaels Idee mit IOS-Latin-1 bringt mich entscheiden weiter :thumbsup:


    C-Quellcode

    1. NSString *escapedString4 = [self.playerChat.text stringByAddingPercentEscapesUsingEncoding:NSISOLatin1StringEncoding];
    Alle Ü Ä Ö å Å usw. funktionieren jetzt perfekt.

    Für das Apostroph habe ich noch keine Lösung. Das macht den NNString "kaputt" ich nehme an, dass " auch problematisch wird.
    Ich werde die 2-3 Char notfalls "von Hand" bearbeiten.

    Ein weiteres zu lösendes Problem:
    stringByAddingPercentEscapesUsingEncoding:' is deprecated, aber das bekomme ich schon noch gelöst 8) (sagte er und verschwand im Chaos)
    Ich habe auch keine Loesung, aber ich bewundere das Problem!
    _____________________________________________________


  • hape42 schrieb:

    Zwischenergebnis:

    Der Vorschlag von MCDan & MyMattes bringt auch keine Verbesserung. zusätzlich hätte ich noch das Problem zu lösen dass ich die durch die übertragene URL erzeugte HTMLseite als return brauche. Darum kam ich überhaupt auf NSData *matchHtmlData = [NSData dataWithContentsOfURL:urlMatch];

    Bei Verwendung von NSURLSessionDataTask erhältst Du die Rückgabe des Servers als NSData in dem CompletionHandler.

    dataWithContentsOfURL: arbeitet synchron und sollte nicht verwendet werden, da damit der entsprechende Thread blockiert wird. Da wirst Du dann früher oder später eh bei NSURLSession landen.
  • MCDan schrieb:

    hape42 schrieb:

    Zwischenergebnis:

    Der Vorschlag von MCDan & MyMattes bringt auch keine Verbesserung. zusätzlich hätte ich noch das Problem zu lösen dass ich die durch die übertragene URL erzeugte HTMLseite als return brauche. Darum kam ich überhaupt auf NSData *matchHtmlData = [NSData dataWithContentsOfURL:urlMatch];
    Bei Verwendung von NSURLSessionDataTask erhältst Du die Rückgabe des Servers als NSData in dem CompletionHandler.

    dataWithContentsOfURL: arbeitet synchron und sollte nicht verwendet werden, da damit der entsprechende Thread blockiert wird. Da wirst Du dann früher oder später eh bei NSURLSession landen.
    Jep, steht auch hier noch mals unter important

    developer.apple.com/documentat…245-datawithcontentsofurl
  • MCDan schrieb:



    dataWithContentsOfURL: arbeitet synchron und sollte nicht verwendet werden, da damit der entsprechende Thread blockiert wird.
    das muss sogar blockiert werden. Es ist ein Spiel bei dem es ähnlich wie bei Schach um den nächsten Zug geht. Und das Board kann erst korrekt angezeigt werden, wenn der Zug abgeschlossen ist.

    Asynchron nützt hier nichts, da ich ja sowieso auf das Ergebnis warten muss
    Ich habe auch keine Loesung, aber ich bewundere das Problem!
    _____________________________________________________


  • hape42 schrieb:

    MCDan schrieb:

    dataWithContentsOfURL: arbeitet synchron und sollte nicht verwendet werden, da damit der entsprechende Thread blockiert wird.
    das muss sogar blockiert werden. Es ist ein Spiel bei dem es ähnlich wie bei Schach um den nächsten Zug geht. Und das Board kann erst korrekt angezeigt werden, wenn der Zug abgeschlossen ist.
    Asynchron nützt hier nichts, da ich ja sowieso auf das Ergebnis warten muss
    Dann solltest du das trotzdem asynchron abfragen und solange ein "Bitte Warten" oder sonstiges View öffnen.

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)