programing

신속 - URL 인코딩

testmans 2023. 5. 15. 21:21
반응형

신속 - URL 인코딩

다음과 같은 문자열을 인코딩하는 경우:

var escapedString = originalString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)

요 그것은피수없 습다니할를슬시래▁it다없니./.

다음 목표 C 코드를 검색해 보았습니다.

NSString *encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
                        NULL,
                        (CFStringRef)unencodedString,
                        NULL,
                        (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                        kCFStringEncodingUTF8 );

URL을 인코딩하는 더 쉬운 방법이 있습니까? 그렇지 않다면 Swift에서 어떻게 작성합니까?

스위프트 3

스위프트 3에는 다음이 있습니다.addingPercentEncoding

let originalString = "test/test"
let escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
print(escapedString!)

출력:

테스트%2F 테스트

스위프트 1

iOS 7 이상에서는 다음과 같은 기능이 있습니다.stringByAddingPercentEncodingWithAllowedCharacters

var originalString = "test/test"
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())
println("escapedString: \(escapedString)")

출력:

테스트%2F 테스트

다음은 유용한(반전된) 문자 집합입니다.

URLFragmentAllowedCharacterSet  "#%<>[\]^`{|}
URLHostAllowedCharacterSet      "#%/<>?@\^`{|}
URLPasswordAllowedCharacterSet  "#%/:<>?@[\]^`{|}
URLPathAllowedCharacterSet      "#%;<>?[\]^`{|}
URLQueryAllowedCharacterSet     "#%<>[\]^`{|}
URLUserAllowedCharacterSet      "#%/:<>?@[\]^`

다른 문자 집합을 이스케이프하려면 집합을 만듭니다.
"" 예: "=" :

var originalString = "test/test=42"
var customAllowedSet =  NSCharacterSet(charactersInString:"=\"#%/<>?@\\^`{|}").invertedSet
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(customAllowedSet)
println("escapedString: \(escapedString)")

출력:

테스트%2F 테스트%3D42

집합에 없는 ASCII 문자를 확인하는 예:

func printCharactersInSet(set: NSCharacterSet) {
    var characters = ""
    let iSet = set.invertedSet
    for i: UInt32 in 32..<127 {
        let c = Character(UnicodeScalar(i))
        if iSet.longCharacterIsMember(i) {
            characters = characters + String(c)
        }
    }
    print("characters not in set: \'\(characters)\'")
}

URL 구성 요소를 사용하면 쿼리 문자열을 수동으로 퍼센트 인코딩하지 않아도 됩니다.

let scheme = "https"
let host = "www.google.com"
let path = "/search"
let queryItem = URLQueryItem(name: "q", value: "Formula One")


var urlComponents = URLComponents()
urlComponents.scheme = scheme
urlComponents.host = host
urlComponents.path = path
urlComponents.queryItems = [queryItem]

if let url = urlComponents.url {
    print(url)   // "https://www.google.com/search?q=Formula%20One"
}

extension URLComponents {
    init(scheme: String = "https",
         host: String = "www.google.com",
         path: String = "/search",
         queryItems: [URLQueryItem]) {
        self.init()
        self.scheme = scheme
        self.host = host
        self.path = path
        self.queryItems = queryItems
    }
}

let query = "Formula One"
if let url = URLComponents(queryItems: [URLQueryItem(name: "q", value: query)]).url {
    print(url)  // https://www.google.com/search?q=Formula%20One
}

스위프트 4 & 5

URL을 사용하여 ..alphanumerics문자 집합 가장 쉬운 옵션:

let urlEncoded = value.addingPercentEncoding(withAllowedCharacters: .alphanumerics)
let url = "http://www.example.com/?name=\(urlEncoded!)"

인코딩에 (예: URL 에인문예집합사용자준표코:.urlQueryAllowed또는.urlHostAllowed를 제외하지 않기 때문에 작동하지 않습니다.=또는&성격.

를 사용하여 확인합니다..alphanumerics가 없는 예 인딩할필요없예인문다니합코딩자를일부는코가:-,.,_또는~제2.3절 RFC 3986의 예약되지 않은 문자).을 사용합니다..alphanumerics사용자 지정 문자 집합을 구성하는 것보다 간단하며 일부 추가 문자를 인코딩해도 상관 없습니다.문제가 발생하면 URL 문자열을 인코딩하는 방법에 설명된 대로 다음과 같은 사용자 지정 문자 집합을 구성합니다.

// Store allowed character set for reuse (computed lazily).
private let urlAllowed: CharacterSet =
    .alphanumerics.union(.init(charactersIn: "-._~")) // as per RFC 3986

extension String {
    var urlEncoded: String? {
        return addingPercentEncoding(withAllowedCharacters: urlAllowed)
    }
}

let url = "http://www.example.com/?name=\(value.urlEncoded!)"

경고:urlEncoded매개 변수가 강제로 래핑 해제되었습니다.잘못된 유니코드 문자열의 경우 충돌할 수 있습니다.String.addingPercentEncoding()의 반환 값이 선택적인 이유를 참조하십시오.강제로 포장을 푸는 대신urlEncoded!사용할 수 있습니다.urlEncoded ?? ""또는if let urlEncoded = urlEncoded { ... }.

스위프트 5:

extension String {
    var urlEncoded: String? {
        let allowedCharacterSet = CharacterSet.alphanumerics.union(CharacterSet(charactersIn: "~-_."))
        return self.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet)
    }
}

print("\u{48}ello\u{9}world\u{7}\u{0}".urlEncoded!) // prints Hello%09world%07%00
print("The string ü@foo-bar".urlEncoded!) // prints The%20string%20%C3%BC%40foo-bar


스위프트 3:

let originalString = "http://www.ihtc.cc?name=htc&title=iOS开发工程师"

인코딩 쿼리:

let escapedString = originalString.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)

결과:

"http://www.ihtc.cc?name=htc&title=iOS%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88" 

인코딩URL:

let escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)

결과:

"http:%2F%2Fwww.ihtc.cc%3Fname=htc&title=iOS%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88"

Swift 4 & 5 (제안에 대해 @sumizome에게 감사합니다.테스트해 주셔서 @FD_와 @derickito에 감사드립니다.)

var allowedQueryParamAndKey = NSCharacterSet.urlQueryAllowed
allowedQueryParamAndKey.remove(charactersIn: ";/?:@&=+$, ")
paramOrKey.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey)

스위프트 3

let allowedQueryParamAndKey =  NSCharacterSet.urlQueryAllowed.remove(charactersIn: ";/?:@&=+$, ")
paramOrKey.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey)

Swift 2.2 (Zaph's에서 빌려서 url 쿼리 키 및 파라미터 값 수정)

var allowedQueryParamAndKey =  NSCharacterSet(charactersInString: ";/?:@&=+$, ").invertedSet
paramOrKey.stringByAddingPercentEncodingWithAllowedCharacters(allowedQueryParamAndKey)

예:

let paramOrKey = "https://some.website.com/path/to/page.srf?a=1&b=2#top"
paramOrKey.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey)
// produces:
"https%3A%2F%2Fsome.website.com%2Fpath%2Fto%2Fpage.srf%3Fa%3D1%26b%3D2%23top"

이것은 브라이언 첸의 대답의 짧은 버전입니다.ㅠㅠurlQueryAllowed는 컨트롤 문자가 쿼리 문자열에서 키 또는 값의 일부를 형성하지 않는 한 이스케이프해야 하는 지점을 통과할 수 있도록 허용합니다.

스위프트 4:

이는 서버가 따르는 인코딩 규칙에 따라 달라집니다.

Apple은 이 클래스 메소드를 제공하지만 어떤 종류의 RCF 프로토콜을 따르는지는 보고하지 않습니다.

var escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!

유용한 도구에 따라 매개 변수에 대한 이러한 문자 인코딩을 보장해야 합니다.

  • (달러 기호) %24가 됨
  • (암퍼샌드) %26이 됩니다.
  • (플러스)가 %2이 됩니다.b
  • (Comma) %2C가 됨
  • (콜론)이 %3이 됩니다.a
  • (Semi-Colon)이 %3이 됩니다.b
  • (동등) %3이 됩니다.d
  • (질문 표시)가 %3이 됩니다.f
  • (상업 A / 장소)가 %40이 됩니다.

즉, URL 인코딩에 대해 말하자면 RFC 1738 프로토콜을 따라야 합니다.

를 들어 Swift는 + char 인코딩을 다루지 않지만 이 세 개의 @: ? char에서 잘 작동합니다.

따라서 매개 변수를 올바르게 인코딩하려면.urlHostAllowed옵션으로는 충분하지 않습니다. 다음과 같이 특수 문자도 추가해야 합니다.

encodedParameter = parameter.replacingOccurrences(of: "+", with: "%2B")

이것이 이러한 정보를 검색하는 데 미친 사람에게 도움이 되기를 바랍니다.

모든 것이 같습니다.

var str = CFURLCreateStringByAddingPercentEscapes(
    nil,
    "test/test",
    nil,
    "!*'();:@&=+$,/?%#[]",
    CFStringBuiltInEncodings.UTF8.rawValue
)

// test%2Ftest

스위프트 4.2

빠른 한 줄 솔루션.를 바꿉니다.originalString인코딩할 문자열을 사용합니다.

var encodedString = originalString.addingPercentEncoding(withAllowedCharacters: CharacterSet(charactersIn: "!*'();:@&=+$,/?%#[]{} ").inverted)

온라인 놀이터 데모

이것은 Swift 5에서 저를 위해 작동합니다.사용 사례는 이미 이스케이프된 문자가 있을 수 있지만 유니코드 문자가 포함된 클립보드 또는 유사한 URL을 가져오는 것입니다.URLComponents또는URL(string:)실패하게 될 것입니다.

먼저 모든 URL-법적 문자를 포함하는 문자 집합을 만듭니다.

extension CharacterSet {

    /// Characters valid in at least one part of a URL.
    ///
    /// These characters are not allowed in ALL parts of a URL; each part has different requirements. This set is useful for checking for Unicode characters that need to be percent encoded before performing a validity check on individual URL components.
    static var urlAllowedCharacters: CharacterSet {
        // Start by including hash, which isn't in any set
        var characters = CharacterSet(charactersIn: "#")
        // All URL-legal characters
        characters.formUnion(.urlUserAllowed)
        characters.formUnion(.urlPasswordAllowed)
        characters.formUnion(.urlHostAllowed)
        characters.formUnion(.urlPathAllowed)
        characters.formUnion(.urlQueryAllowed)
        characters.formUnion(.urlFragmentAllowed)

        return characters
    }
}

다음으로, 다음, 장확을 합니다.StringURL을 인코딩하는 방법을 사용합니다.

extension String {

    /// Converts a string to a percent-encoded URL, including Unicode characters.
    ///
    /// - Returns: An encoded URL if all steps succeed, otherwise nil.
    func encodedUrl() -> URL? {        
        // Remove preexisting encoding,
        guard let decodedString = self.removingPercentEncoding,
            // encode any Unicode characters so URLComponents doesn't choke,
            let unicodeEncodedString = decodedString.addingPercentEncoding(withAllowedCharacters: .urlAllowedCharacters),
            // break into components to use proper encoding for each part,
            let components = URLComponents(string: unicodeEncodedString),
            // and reencode, to revert decoding while encoding missed characters.
            let percentEncodedUrl = components.url else {
            // Encoding failed
            return nil
        }

        return percentEncodedUrl
    }

}

다음과 같이 테스트할 수 있습니다.

let urlText = "https://www.example.com/폴더/search?q=123&foo=bar&multi=eggs+and+ham&hangul=한글&spaced=lovely%20spam&illegal=<>#top"
let url = encodedUrl(from: urlText)

값 값url 마에막지:https://www.example.com/%ED%8F%B4%EB%8D%94/search?q=123&foo=bar&multi=eggs+and+ham&hangul=%ED%95%9C%EA%B8%80&spaced=lovely%20spam&illegal=%3C%3E#top

가지 모두 둘에 하십시오.%20그리고.+문자는 되며 보되고존문은인, 유코드니됩다코딩자는니공백▁spacing다▁the▁are니,▁unicode됩인코,▁preserved딩ers▁charact문.%20urlText이중 부호화되지 않은 경우, 그리고 앵커(또는#이 남아 있습니다.이 남아 있습니다.

편집: 이제 각 구성 요소의 유효성을 확인합니다.

Swift 5에서 문자열을 종료하는 경우

func escape(string: String) -> String {
    let allowedCharacters = string.addingPercentEncoding(withAllowedCharacters: CharacterSet(charactersIn: ":=\"#%/<>?@\\^`{|}").inverted) ?? ""
    return allowedCharacters
}

어떻게 사용합니까?

let strEncoded = self.escape(string: "http://www.edamam.com/ontologies/edamam.owl#recipe_e2a1b9bf2d996cbd9875b80612ed9aa4")
print("escapedString: \(strEncoded)")

이것이 필요했기 때문에 저는 URL 인코딩 문자열과 더 일반적인 종료 목표를 모두 허용하는 문자열 확장자를 작성하여 매개 변수 사전을 "GET" 스타일 URL 매개 변수로 변환했습니다.

extension String {
    func URLEncodedString() -> String? {
        var escapedString = self.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
        return escapedString
    }
    static func queryStringFromParameters(parameters: Dictionary<String,String>) -> String? {
        if (parameters.count == 0)
        {
            return nil
        }
        var queryString : String? = nil
        for (key, value) in parameters {
            if let encodedKey = key.URLEncodedString() {
                if let encodedValue = value.URLEncodedString() {
                    if queryString == nil
                    {
                        queryString = "?"
                    }
                    else
                    {
                        queryString! += "&"
                    }
                    queryString! += encodedKey + "=" + encodedValue
                }
            }
        }
        return queryString
    }
}

맛있게 드세요!

이것은 나에게 효과가 있습니다.

func stringByAddingPercentEncodingForFormData(plusForSpace: Bool=false) -> String? {

    let unreserved = "*-._"
    let allowed = NSMutableCharacterSet.alphanumericCharacterSet()
    allowed.addCharactersInString(unreserved)

    if plusForSpace {
        allowed.addCharactersInString(" ")
    }

    var encoded = stringByAddingPercentEncodingWithAllowedCharacters(allowed)

    if plusForSpace {
        encoded = encoded?.stringByReplacingOccurrencesOfString(" ", withString: "+")
    }
    return encoded
}

저는 위의 기능을 이 링크에서 찾았습니다: http://useyourloaf.com/blog/how-to-percent-encode-a-url-string/ .

let Url = URL(string: urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "")

이 대답들 중 어떤 것도 저에게 효과가 없었습니다.url에 영어가 아닌 문자가 포함되어 있을 때 앱이 중단되었습니다.

 let unreserved = "-._~/?%$!:"
 let allowed = NSMutableCharacterSet.alphanumeric()
     allowed.addCharacters(in: unreserved)

 let escapedString = urlString.addingPercentEncoding(withAllowedCharacters: allowed as CharacterSet)

수행하려는 작업의 매개 변수에 따라 고유한 문자 집합을 만들기만 하면 됩니다.하고, 위는영문허용고하를자어,고허하▁the▁for위어용▁english▁characters▁above▁allows,,-._~/?%$!:

제게 도움이 된 것은 제가 별도로 만든 것입니다.NSCharacterSet필요한 결과를 생성하기 위해 UTF-8 인코딩 문자열, 즉 textToEncode에서 사용했습니다.

var queryCharSet = NSCharacterSet.urlQueryAllowed
queryCharSet.remove(charactersIn: "+&?,:;@+=$*()")
    
let utfedCharacterSet = String(utf8String: textToEncode.cString(using: .utf8)!)!
let encodedStr = utfedCharacterSet.addingPercentEncoding(withAllowedCharacters: queryCharSet)!
    
let paramUrl = "https://api.abc.eu/api/search?device=true&query=\(escapedStr)"

SWIFT 4.2

때때로 이런 일이 발생하는 이유는 슬래그에 공간이 있거나 API URL을 통과하는 매개 변수에 대한 URL 인코딩이 없기 때문입니다.

let myString = self.slugValue
                let csCopy = CharacterSet(bitmapRepresentation: CharacterSet.urlPathAllowed.bitmapRepresentation)
                let escapedString = myString!.addingPercentEncoding(withAllowedCharacters: csCopy)!
                //always "info:hello%20world"
                print(escapedString)

참고: 다음에 대한 내용을 살펴보십시오.bitmapRepresentation.

버전:스위프트 5

// space convert to +
let mstring = string.replacingOccurrences(of: " ", with: "+")
// remove special character
var allowedQueryParamAndKey = NSCharacterSet.urlQueryAllowed
allowedQueryParamAndKey.remove(charactersIn: "!*'\"();:@&=+$,/?%#[]%")
return mstring.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey) ?? mstring  

Swift 5 아래와 같은 문자열을 인코딩하려면 .afURLQueryAllowed 옵션을 사용할 수 있습니다.

let testString = "6hAD9/RjY+SnGm&B"
let escodedString = testString.addingPercentEncoding(withAllowedCharacters: .afURLQueryAllowed)
print(escodedString!) 

//문자열은 en6h와 같습니다.AD9%2FRJY%2BSnGm%26

언급URL : https://stackoverflow.com/questions/24551816/swift-encode-url

반응형