golang encodeURIComponent

import (
    "net/url"
    "strings"
)
// 可以通过修改底层url.QueryEscape代码获得更高的效率,很简单
func encodeURIComponent(str string) string {
    r := url.QueryEscape(str)
    r = strings.Replace(r, "+", "%20", -1)
    return r
}

go的url.QueryEscape与js的encodeURIComponent是不一样的,主要体现在对空格的处理,此函数编码后的字符串可以被js的decodeURIComponent正确还原
测试代码如下:


foo(";,/?:@&=+$", "%3B%2C%2F%3F%3A%40%26%3D%2B%24")
foo("-_.!~*'()", "-_.!~*'()")
foo("#", "%23")
foo("ABC abc 123", "ABC%20abc%20123")
foo("hello java", "hello%20java")
foo("~`!@#£€$()*^&°%§¥¢?.,<>'\";:/|[]{}=+_- ", "~%60!%40%23%C3%82%C2%A3%C3%A2%E2%80%9A%C2%AC%24()*%5E%26%C3%82%C2%B0%25%C3%82%C2%A7%C3%82%C2%A5%C3%82%C2%A2%3F.%2C%3C%3E'%22%3B%3A%2F%7C%5B%5D%7B%7D%3D%2B_-%20")
foo("#this is a test", "%23this%20is%20a%20test")
foo("#foo bar$", "%23foo%20bar%24")
foo("test with different chars like çşöüğİı", "test%20with%20different%20chars%20like%20%C3%83%C2%A7%C3%85%C5%B8%C3%83%C2%B6%C3%83%C2%BC%C3%84%C5%B8%C3%84%C2%B0%C3%84%C2%B1")
foo("$ %20F%20@", "%24%20%2520F%2520%40")
foo(" %20F %20 +", "%20%2520F%20%2520%20%2B")
foo("%40F%20F%10F", "%2540F%2520F%2510F")
foo(" + %20 + ", "%20%2B%20%2520%20%2B%20")
foo("%20 %20 %20 %20F", "%2520%20%2520%20%2520%20%2520F")
foo("'%20F'", "'%2520F'")
foo("@%40@", "%40%2540%40")
foo(" test ", "%20test%20")
foo("$#%23#$", "%24%23%2523%23%24")
foo("   %20   ", "%20%20%20%2520%20%20%20")
foo("^â%5E", "%5E%C3%83%C2%A2%255E")
foo("({foo &%26 bar})", "(%7Bfoo%20%26%2526%20bar%7D)")
foo("\uD800\uDFFF", "%F0%90%8F%BF")
foo("中国", "%E4%B8%AD%E5%9B%BD")

function foo(src, dist) {
    const r = encodeURIComponent(src)
    if (r !== dist) {
        console.log('enc:', src, dist, r)
    }
    const de  = decodeURIComponent(dist)
    if(de !== src){
        console.log('dec:', dist, src, r)
    }
}

const str  = "\uD800\uDFFF"
console.log(str.length)
console.log(Buffer.from(str))



foo("({foo &%26 bar})","%28%7Bfoo%20%26%2526%20bar%7D%29")


下面是go语言的测试代码:

package main

import (
    "fmt"
    "net/url"
    "strings"
)

func encodeURIComponent(str string) string {
    r := url.QueryEscape(str)
    r = strings.Replace(r, "+", "%20", -1)
    return r
}

func paif(err error) {
    if err != nil {
        panic(err)
    }
}

func main() {
    // fmt.Println("\UD800DFFF")
    // foo("\uD800\uDFFF", )
    fmt.Println("\xe4\xb8\x96")
    r, err := url.QueryUnescape("%F0%90%8F%BF")
    paif(err)
    fmt.Println("rrr:", r)
    fmt.Println("r222:", encodeURIComponent(r))

    foo(";,/?:@&=+$", "%3B%2C%2F%3F%3A%40%26%3D%2B%24")
    foo("-_.!~*'()", "-_.!~*'()")
    foo("#", "%23")
    foo("ABC abc 123", "ABC%20abc%20123")
    foo("hello java", "hello%20java")
    foo("~`!@#£€$()*^&°%§¥¢?.,<>'\";:/|[]{}=+_- ", "~%60!%40%23%C3%82%C2%A3%C3%A2%E2%80%9A%C2%AC%24()*%5E%26%C3%82%C2%B0%25%C3%82%C2%A7%C3%82%C2%A5%C3%82%C2%A2%3F.%2C%3C%3E'%22%3B%3A%2F%7C%5B%5D%7B%7D%3D%2B_-%20")
    foo("#this is a test", "%23this%20is%20a%20test")
    foo("#foo bar$", "%23foo%20bar%24")
    foo("test with different chars like çşöüğİı", "test%20with%20different%20chars%20like%20%C3%83%C2%A7%C3%85%C5%B8%C3%83%C2%B6%C3%83%C2%BC%C3%84%C5%B8%C3%84%C2%B0%C3%84%C2%B1")
    foo("$ %20F%20@", "%24%20%2520F%2520%40")
    foo(" %20F %20 +", "%20%2520F%20%2520%20%2B")
    foo("%40F%20F%10F", "%2540F%2520F%2510F")
    foo(" + %20 + ", "%20%2B%20%2520%20%2B%20")
    foo("%20 %20 %20 %20F", "%2520%20%2520%20%2520%20%2520F")
    foo("'%20F'", "'%2520F'")
    foo("@%40@", "%40%2540%40")
    foo(" test ", "%20test%20")
    foo("$#%23#$", "%24%23%2523%23%24")
    foo("   %20   ", "%20%20%20%2520%20%20%20")
    foo("^â%5E", "%5E%C3%83%C2%A2%255E")
    foo("({foo &%26 bar})", "(%7Bfoo%20%26%2526%20bar%7D)")
    // foo("\uD800\uDFFF", "%F0%90%8F%BF")
    // foo("\xD8\x00\xDF\xFF", "%F0%90%8F%BF")
    foo("中国", "%E4%B8%AD%E5%9B%BD")
}

func foo(src string, dist string) {
    r := url.QueryEscape(src)
    r = strings.Replace(r, "+", "%20", -1)
    if r != dist {
        fmt.Printf("ensrc:%s\ngo:%s\njs:%s\n\n", src, r, dist)
    }

    r, err := url.QueryUnescape(dist)
    paif(err)
    if r != src {
        fmt.Printf("desrc:%s\ngo:%s\njs:%s\n\n", src, r, dist)
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值