ios 如何在 Swift 中对 URL 进行编码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24879659/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to encode a URL in Swift
提问by user3541467
This is my URL
.
这是我的URL
。
The problem is, that the address
field is not being appended to urlpath
.
问题是,该address
字段没有附加到urlpath
.
Does anyone know why that is?
有谁知道这是为什么?
var address:string
address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
let urlpath = NSString(format: "http://maps.googleapis.com/maps/api/geocode/json?address="+"\(address)")
回答by Bryan Chen
Swift 4.2
斯威夫特 4.2
var urlString = originalString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
Swift 3.0
斯威夫特 3.0
var address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
let escapedAddress = address.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
let urlpath = String(format: "http://maps.googleapis.com/maps/api/geocode/json?address=\(escapedAddress)")
Use stringByAddingPercentEncodingWithAllowedCharacters
:
使用stringByAddingPercentEncodingWithAllowedCharacters
:
var escapedAddress = address.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
Use Deprecated in iOS 9 and OS X v10.11stringByAddingPercentEscapesUsingEncoding:
用 在 iOS 9 和 OS X v10.11 中已弃用stringByAddingPercentEscapesUsingEncoding:
var address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
var escapedAddress = address.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
let urlpath = NSString(format: "http://maps.googleapis.com/maps/api/geocode/json?address=\(escapedAddress)")
回答by Rob
If it's possible that the value that you're adding to your URL can have reserved characters (as defined by section 2 of RFC 3986), you might have to refine your percent-escaping. Notably, while &
and +
are valid characters in a URL, they're not valid within a URL query parameter value (because &
is used as delimiter between query parameters which would prematurely terminate your value, and +
is translated to a space character). Unfortunately, the standard percent-escaping leaves those delimiters unescaped.
如果您添加到 URL 的值可能具有保留字符(如RFC 3986的第 2 节所定义),则您可能需要优化百分比转义。值得注意的是,虽然&
和+
是 URL 中的有效字符,但它们在 URL 查询参数值中无效(因为&
用作查询参数之间的分隔符,这会过早终止您的值,并被+
转换为空格字符)。不幸的是,标准的百分比转义使那些分隔符未转义。
Thus, you might want to percent escape all characters that are not within RFC 3986's list of unreserved characters:
因此,您可能希望对不在 RFC 3986 的未保留字符列表中的所有字符进行百分比转义:
Characters that are allowed in a URI but do not have a reserved purpose are called unreserved. These include uppercase and lowercase letters, decimal digits, hyphen, period, underscore, and tilde.
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
URI 中允许但没有保留用途的字符称为未保留。其中包括大写和小写字母、十进制数字、连字符、句点、下划线和波浪号。
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
Later, in section 3.4, the RFC further contemplates adding ?
and /
to the list of allowed characters within a query:
稍后,在第 3.4 节中,RFC 进一步考虑将?
和添加/
到查询中的允许字符列表:
The characters slash ("/") and question mark ("?") may represent data within the query component. Beware that some older, erroneous implementations may not handle such data correctly when it is used as the base URI for relative references (Section 5.1), apparently because they fail to distinguish query data from path data when looking for hierarchical separators. However, as query components are often used to carry identifying information in the form of "key=value" pairs and one frequently used value is a reference to another URI, it is sometimes better for usability to avoid percent- encoding those characters.
字符斜杠(“/”)和问号(“?”)可以代表查询组件内的数据。请注意,当这些数据用作相对引用的基本 URI(第 5.1 节)时,一些较旧的、错误的实现可能无法正确处理此类数据,这显然是因为它们在查找分层分隔符时无法区分查询数据和路径数据。但是,由于查询组件通常用于以“键=值”对的形式携带标识信息,并且一个经常使用的值是对另一个 URI 的引用,因此有时避免对这些字符进行百分比编码会更好地提高可用性。
Nowadays, you'd generally use URLComponents
to percent escape the query value:
如今,您通常会使用URLComponents
百分比转义查询值:
var address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
var components = URLComponents(string: "http://maps.googleapis.com/maps/api/geocode/json")!
components.queryItems = [URLQueryItem(name: "address", value: address)]
let url = components.url!
By the way, while it's not contemplated in the aforementioned RFC, section 5.2, URL-encoded form data, of the W3C HTML spec says that application/x-www-form-urlencoded
requests should also replace space characters with +
characters (and includes the asterisk in the characters that should not be escaped). And, unfortunately, URLComponents
won't properly percent escape this, so Apple advises that you manually percent escape it before retrieving the url
property of the URLComponents
object:
顺便说一下,虽然在上述 RFC 中没有考虑,但 W3C HTML 规范的第 5.2 节 URL-encoded form data说application/x-www-form-urlencoded
请求也应该用+
字符替换空格字符(并且在不应该转义的字符中包含星号)。而且,不幸的是,URLComponents
不会正确地转义它,因此 Apple 建议您在检索对象的url
属性之前手动对其进行百分比转义URLComponents
:
// configure `components` as shown above, and then:
components.percentEncodedQuery = components.percentEncodedQuery?.replacingOccurrences(of: "+", with: "%2B")
let url = components.url!
For Swift 2 rendition, where I manually do all of this percent escaping myself, see the previous revision of this answer.
回答by Yusuf X
Swift 3:
斯威夫特 3:
let escapedString = originalString.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)
回答by quemeful
Swift 2.0
斯威夫特 2.0
let needsLove = "string needin some URL love"
let safeURL = needsLove.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
回答by Desmond Hume
URLQueryAllowedCharacterSet
should not be used for URL encoding of query parameters because this charset includes &
, ?
, /
etc. which serve as delimiters in a URL query, e.g.
URLQueryAllowedCharacterSet
不应该用于URL编码的查询参数,因为此charset包括&
,?
,/
等,其作为在一个URL查询定界符,例如
/?paramname=paramvalue¶mname=paramvalue
These characters are allowed in URL queries as a whole but not in parameter values.
这些字符可以作为一个整体出现在 URL 查询中,但不能出现在参数值中。
RFC 3986specifically talks about unreservedcharacters, which are different from allowed:
RFC 3986专门讨论了与允许不同的非保留字符:
2.3. Unreserved Characters
Characters that are allowed in a URI but do not have a reserved
purpose are called unreserved. These include uppercase and lowercase letters, decimal digits, hyphen, period, underscore, and tilde.unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
2.3. 无保留字符
URI 中允许但没有保留
用途的字符称为未保留。其中包括大写和小写字母、十进制数字、连字符、句点、下划线和波浪号。unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
Accordingly:
因此:
extension String {
var URLEncoded:String {
let unreservedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"
let unreservedCharset = NSCharacterSet(charactersInString: unreservedChars)
let encodedString = self.stringByAddingPercentEncodingWithAllowedCharacters(unreservedCharset)
return encodedString ?? self
}
}
The code above doesn't make a call to alphanumericCharacterSet
because of the enormous size of the charset it returns (103806 characters). And in view of how many Unicode characters alphanumericCharacterSet
allows for, using it for the purpose of URL encoding would be simply erroneous.
上面的代码没有调用,alphanumericCharacterSet
因为它返回的字符集很大(103806 个字符)。考虑到 Unicode 字符的alphanumericCharacterSet
数量,将其用于 URL 编码是完全错误的。
Usage:
用法:
let URLEncodedString = myString.URLEncoded
回答by Daryl
Swift 4.1
斯威夫特 4.1
Create a "Character Set" based on the option you want (urlQueryAllowed). Then remove the additional characters you do not want (+&). Then pass that character set to "addingPercentEncoding".
根据您想要的选项 (urlQueryAllowed) 创建一个“字符集”。然后删除您不想要的附加字符 (+&)。然后将该字符集传递给“addingPercentEncoding”。
var address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
var queryCharSet = NSCharacterSet.urlQueryAllowed
queryCharSet.remove(charactersIn: "+&")
let escapedAddress = address.addingPercentEncoding(withAllowedCharacters: queryCharSet)!
let urlpath = String(format: "http://maps.googleapis.com/maps/api/geocode/json?address=\(escapedAddress)")
回答by Ashok R
XCODE 8, SWIFT 3.0
Xcode 8,SWIFT 3.0
From grokswift
来自 grokswift
Creating URLs from strings is a minefield for bugs. Just miss a single / or accidentally URL encode the ? in a query and your API call will fail and your app won't have any data to display (or even crash if you didn't anticipate that possibility). Since iOS 8 there's a better way to build URLs using NSURLComponents
and NSURLQueryItems
.
从字符串创建 URL 是漏洞的雷区。只是错过了一个/或意外的 URL 编码?在查询中,您的 API 调用将失败,您的应用程序将不会显示任何数据(如果您没有预料到这种可能性,甚至会崩溃)。从 iOS 8 开始,有一种更好的方法来使用NSURLComponents
和构建 URL NSURLQueryItems
。
func createURLWithComponents() -> URL? {
var urlComponents = URLComponents()
urlComponents.scheme = "http"
urlComponents.host = "maps.googleapis.com"
urlComponents.path = "/maps/api/geocode/json"
let addressQuery = URLQueryItem(name: "address", value: "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India")
urlComponents.queryItems = [addressQuery]
return urlComponents.url
}
Below is the code to access url using guard
statement.
下面是使用guard
语句访问 url 的代码。
guard let url = createURLWithComponents() else {
print("invalid URL")
return nil
}
print(url)
Output:
输出:
http://maps.googleapis.com/maps/api/geocode/json?address=American%20Tourister,%20Abids%20Road,%20Bogulkunta,%20Hyderabad,%20Andhra%20Pradesh,%20India
Read More: Building URLs With NSURLComponents and NSURLQueryItems
回答by Jorge Ramírez
Just completing Desmond Hume's answer to extend the String class for a RFC 3986 unreserved charactersvalid encoding function (needed if you are encoding query FORM parameters):
刚刚完成 Desmond Hume 的回答以扩展RFC 3986 非保留字符有效编码函数的 String 类(如果您对查询 FORM 参数进行编码,则需要):
Swift 3
斯威夫特 3
extension String {
var RFC3986UnreservedEncoded:String {
let unreservedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"
let unreservedCharsSet: CharacterSet = CharacterSet(charactersIn: unreservedChars)
let encodedString: String = self.addingPercentEncoding(withAllowedCharacters: unreservedCharsSet)!
return encodedString
}
}
回答by Pavlos
Updated for Swift 3:
为 Swift 3 更新:
var escapedAddress = address.addingPercentEncoding(
withAllowedCharacters: CharacterSet.urlQueryAllowed)
回答by vadian
In Mac OS 10.9 Maverics and iOS 7 NSURLComponents
has been introduced which handles the encoding of the different URL parts in a pretty convenient way.
在 Mac OS 10.9 Maverics 和 iOS 7NSURLComponents
中已经引入,它们以一种非常方便的方式处理不同 URL 部分的编码。
The NSURLComponents class is a class that is designed to parse URLs based on RFC 3986 and to construct URLs from their constituent parts. Its behavior differs subtly from the NSURL class, which conforms to older RFCs. However, you can easily obtain an NSURL object based on the contents of a URL components object or vice versa.
NSURLComponents 类是一个旨在根据 RFC 3986 解析 URL 并从其组成部分构造 URL 的类。它的行为与遵循旧 RFC 的 NSURL 类略有不同。但是,您可以根据 URL 组件对象的内容轻松获取 NSURL 对象,反之亦然。
let address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
let components = NSURLComponents(string: "http://maps.googleapis.com/maps/api/geocode/json")!
// create a query item key=value
let queryItem = NSURLQueryItem(name: "address", value: address)
// add the query item to the URL, NSURLComponents takes care of adding the question mark.
components.queryItems = [queryItem]
// get the properly percent encoded string
let urlpath = components.string!
print(urlpath)