So posten Sie Sonderzeichen in Swift

Lesezeit: 5 Minuten

So posten Sie Sonderzeichen in Swift
Benutzer520300

Ich verwende Folgendes, um eine E-Mail und ein Passwort an meinen Server zu senden (php-Skript). Das Problem, das ich habe, ist, dass das Passwort ein Sonderzeichen enthält (insbesondere das & Symbol), das anscheinend abgezogen wird. Ich vermute, weil es denkt, dass seine trennenden Variablen übergeben werden. Wie kann ich dieses Zeichen übergeben, ohne es zu entfernen?

let myURL = NSURL(string: "my script url here")
let request = NSMutableURLRequest(URL: myURL!)
request.HTTPMethod = "POST"

let postString = "email=(userEmailText)&password=(userPasswordText)"

request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)

So posten Sie Sonderzeichen in Swift
rauben

Sie sollten vorsichtig sein mit NSURLComponents weil der NSURLQueryItem könnte das fragliche Zeichen prozentual entkommen, das &, es entgeht dem nicht prozentual + Zeichen (das PHP als Leerzeichen interpretiert, in Übereinstimmung mit dem W3C-Spezifikation für x-www-form-urlencoded). Wie das queryItems Dokumentation sagt:

Notiz

RFC 3986 gibt an, welche Zeichen in der Abfragekomponente einer URL prozentkodiert werden müssen, jedoch nicht, wie diese Zeichen interpretiert werden sollen. Die Verwendung von getrennten Schlüssel-Wert-Paaren ist eine gängige Konvention, aber nicht durch eine Spezifikation standardisiert. Daher können bei anderen Implementierungen, die dieser Konvention folgen, Interoperabilitätsprobleme auftreten.

Ein bemerkenswertes Beispiel für potenzielle Interoperabilitätsprobleme ist, wie das Pluszeichen (+) Charakter wird behandelt:

Gemäß RFC 3986 ist das Pluszeichen ein gültiges Zeichen in einer Abfrage und muss nicht prozentcodiert sein. Allerdings nach W3C-Empfehlungen für die URI-Adressierung, ist das Pluszeichen als Kurzschreibweise für ein Leerzeichen innerhalb einer Abfragezeichenfolge reserviert (z. ?greeting=hello+world).

Dies lässt einige Alternativen für das Escape-Prozent für die Werte übrig, die Sie selbst zur Abfrage der URL hinzufügen, wenn Ihr Wert Folgendes enthalten könnte: + Charakter:

  1. Sie können Ihre eigenen bauen CharacterSet der zu maskierenden Zeichen und verwenden Sie dann addingPercentEncodingForURLQueryValue in Swift 3:

    extension String {
    
        /// Returns a new string made from the `String` by replacing all characters not in the unreserved
        /// character set (as defined by RFC3986) with percent encoded characters.
    
        func addingPercentEncodingForURLQueryValue() -> String? {
            let allowedCharacters = CharacterSet.urlQueryValueAllowed()
            return addingPercentEncoding(withAllowedCharacters: allowedCharacters)
        }
    
    }
    
    extension CharacterSet {
    
        /// Returns the character set for characters allowed in the individual parameters within a query URL component.
        ///
        /// The query component of a URL is the component immediately following a question mark (?).
        /// For example, in the URL `http://www.example.com/index.php?key1=value1#jumpLink`, the query
        /// component is `key1=value1`. The individual parameters of that query would be the key `key1`
        /// and its associated value `value1`.
        ///
        /// According to RFC 3986, the set of unreserved characters includes
        ///
        /// `ALPHA / DIGIT / "-"https://stackoverflow.com/"."https://stackoverflow.com/"_"https://stackoverflow.com/"~"`
        ///
        /// In section 3.4 of the RFC, it further recommends adding `/` and `?` to the list of unescaped characters
        /// for the sake of compatibility with some erroneous implementations, so this routine also allows those
        /// to pass unescaped.
    
    
        static func urlQueryValueAllowed() -> CharacterSet {
            return CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~/?")
        }
    
    }
    
  2. Alamofire verfolgt einen ähnlichen Ansatz, geht dies jedoch aus der anderen Richtung, nämlich dem Ergreifen des .urlQueryAllowed Zeichensatz (der nahe ist, aber nicht ganz richtig) und entfernt reservierte Zeichen, die in RFC 3986 identifiziert wurden. In Swift 3:

    /// Returns a percent-escaped string following RFC 3986 for a query string key or value.
    ///
    /// RFC 3986 states that the following characters are "reserved" characters.
    ///
    /// - General Delimiters: ":", "#", "[", "]", "@", "?", "https://stackoverflow.com/"
    /// - Sub-Delimiters: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "="
    ///
    /// In RFC 3986 - Section 3.4, it states that the "?" and "https://stackoverflow.com/" characters should not be escaped to allow
    /// query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "https://stackoverflow.com/"
    /// should be percent-escaped in the query string.
    ///
    /// - parameter string: The string to be percent-escaped.
    ///
    /// - returns: The percent-escaped string.
    public func escape(_ string: String) -> String {
        let generalDelimitersToEncode = ":#[]@" // does not include "?" or "https://stackoverflow.com/" due to RFC 3986 - Section 3.4
        let subDelimitersToEncode = "!$&'()*+,;="
    
        var allowedCharacterSet = CharacterSet.urlQueryAllowed
        allowedCharacterSet.remove(charactersIn: "(generalDelimitersToEncode)(subDelimitersToEncode)")
    
        var escaped = ""
    
        //==========================================================================================================
        //
        //  Batching is required for escaping due to an internal bug in iOS 8.1 and 8.2. Encoding more than a few
        //  hundred Chinese characters causes various malloc error crashes. To avoid this issue until iOS 8 is no
        //  longer supported, batching MUST be used for encoding. This introduces roughly a 20% overhead. For more
        //  info, please refer to:
        //
        //      - https://github.com/Alamofire/Alamofire/issues/206
        //
        //==========================================================================================================
        if #available(iOS 8.3, *) {
            escaped = string.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) ?? string
        } else {
            let batchSize = 50
            var index = string.startIndex
    
            while index != string.endIndex {
                let startIndex = index
                let endIndex = string.index(index, offsetBy: batchSize, limitedBy: string.endIndex) ?? string.endIndex
                let range = startIndex..<endIndex
    
                let substring = string.substring(with: range)
    
                escaped += substring.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) ?? substring
    
                index = endIndex
            }
        }
    
        return escaped
    }
    

Sie können dann die oben genannten Schritte verwenden, um den Schlüssel und den Wert im Hauptteil der Anfrage prozentual zu maskieren, zum Beispiel:

let parameters = ["email" : email, "password" : password]
request.httpBody = parameters
    .map { (key, value) in
        let escapedKey = key.addingPercentEncodingForURLQueryValue()!
        let escapedValue = value.addingPercentEncodingForURLQueryValue()!
        return "(escapedKey)=(escapedValue)"
    }
    .joined(separator: "&")
    .data(using: .utf8)

Informationen zu den Swift 2-Versionen der oben genannten Informationen finden Sie in der vorherigen Überarbeitung dieser Antwort.

Sie müssen das Kennwort prozentual mit Escapezeichen versehen, bevor Sie es der URL hinzufügen. Besser noch, verwenden Sie NSURLComponents, um Ihre URL zu erstellen und eine Abfragezeichenfolge hinzuzufügen.

  • NSURLComponents lässt Charaktere wie + unentdeckt passieren.

    – Rauben

    22. Dezember ’16 um 1:11

  • Es ist beabsichtigt. Der Dokumentation für NSURLComponents sagt: “Ein bemerkenswertes Beispiel für potenzielle Interoperabilitätsprobleme ist, wie das Pluszeichen (+) Zeichen wird behandelt … möglicherweise müssen Sie das Pluszeichen präventiv prozentkodieren.” URLQueryItem, wird es dann falsch prozentual kodieren % des Prozentsatzes kodiert + Reihenfolge! Schränkt die Nützlichkeit von ernsthaft ein NSURLComponents, MEINER BESCHEIDENEN MEINUNG NACH.

    – Rauben

    22. Mai ’17 bei 0:51


Hier ist ein Beispielcode, den Sie in einem Playground ausprobieren können.

//: Playground - noun: a place where people can play

import UIKit

var n = NSURLComponents()

let s = "blah"
// Note that the values here should not be % encoded
let item1 = NSURLQueryItem(name: "password1", value: "ab%&")
let item2 = NSURLQueryItem(name: "password2", value: "ab%&%#$%^&*(")

n.queryItems = [item1, item2]

n.URL?.query

n.queryItems?.count

n.queryItems![0].name
n.queryItems![0].value

n.queryItems![1].name
n.queryItems![1].value

n.URL

  • Ärgerlich, NSURLQueryItem lässt bestimmte Sonderzeichen ohne Escapezeichen passieren (zB +).

    – Rauben

    22. Dezember ’16 um 1:11

.

485480cookie-checkSo posten Sie Sonderzeichen in Swift

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy