gpt4 book ai didi

php - 如何在 swift 中 http 发布特殊字符

转载 作者:搜寻专家 更新时间:2023-10-31 22:13:56 26 4
gpt4 key购买 nike

我正在使用以下内容将电子邮件和密码发送到我的服务器(php 脚本)。我遇到的问题是密码包含一个特殊的字符(特别是 & 符号),它似乎被剥离了。我想是因为它认为它的分隔变量被传递了。我如何在不剥离它的情况下传递这个字符?

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)

最佳答案

你应该小心使用 NSURLComponents 因为 NSURLQueryItem 可能会百分号转义有问题的字符,&,它不会百分比转义 + 字符(PHP 将解释为符合 W3C Specification for x-www-form-urlencoded 的空格)。正如 the queryItems documentation 所说:

Note

RFC 3986 specifies which characters must be percent-encoded in the query component of a URL, but not how those characters should be interpreted. The use of delimited key-value pairs is a common convention, but isn't standardized by a specification. Therefore, you may encounter interoperability problems with other implementations that follow this convention.

One notable example of potential interoperability problems is how the plus sign (+) character is handled:

According to RFC 3986, the plus sign is a valid character within a query, and doesn't need to be percent-encoded. However, according to the W3C recommendations for URI addressing, the plus sign is reserved as shorthand notation for a space within a query string (for example, ?greeting=hello+world).

如果您的值可能包含 + 字符,那么对于您自己添加到 URL 查询的值,这会留下一些百分比转义选项:

  1. 您可以构建自己的要转义字符的 CharacterSet,然后在 Swift 3 中使用 addingPercentEncodingForURLQueryValue:

    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 / "-" / "." / "_" / "~"`
    ///
    /// 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 采用了类似的方法,但从另一个方向进行,即抓取 .urlQueryAllowed 字符集(接近但不太正确),并取出保留字符在 RFC 3986 中确定。在 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: ":", "#", "[", "]", "@", "?", "/"
    /// - Sub-Delimiters: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "="
    ///
    /// In RFC 3986 - Section 3.4, it states that the "?" and "/" characters should not be escaped to allow
    /// query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "/"
    /// 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 "/" 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
    }

然后您可以使用上面的代码对请求正文中的键和值进行百分比转义,例如:

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)

有关上述内容的 Swift 2 版本,请参阅 previous revision of this answer

关于php - 如何在 swift 中 http 发布特殊字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35905347/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com