Encode / decode URLs
Solution 1:
You can do all the URL encoding you want with the net/url module. It doesn't break out the individual encoding functions for the parts of the URL, you have to let it construct the whole URL. Having had a squint at the source code I think it does a very good and standards compliant job.
Here is an example (playground link)
package main
import (
"fmt"
"net/url"
)
func main() {
Url, err := url.Parse("http://www.example.com")
if err != nil {
panic("boom")
}
Url.Path += "/some/path/or/other_with_funny_characters?_or_not/"
parameters := url.Values{}
parameters.Add("hello", "42")
parameters.Add("hello", "54")
parameters.Add("vegetable", "potato")
Url.RawQuery = parameters.Encode()
fmt.Printf("Encoded URL is %q\n", Url.String())
}
Which prints
Encoded URL is "http://www.example.com/some/path/or/other_with_funny_characters%3F_or_not/?vegetable=potato&hello=42&hello=54"
Solution 2:
From MDN on encodeURIComponent:
encodeURIComponent escapes all characters except the following: alphabetic, decimal digits,
'-', '_', '.', '!', '~', '*', ''', '(', ')'
From Go's implementation of url.QueryEscape (specifically, the shouldEscape
private function), escapes all characters except the following: alphabetic, decimal digits, '-', '_', '.', '~'
.
Unlike Javascript, Go's QueryEscape() will escape '!', '*', ''', '(', ')'
. Basically, Go's version is strictly RFC-3986 compliant. Javascript's is looser. Again from MDN:
If one wishes to be more stringent in adhering to RFC 3986 (which reserves !, ', (, ), and *), even though these characters have no formalized URI delimiting uses, the following can be safely used:
function fixedEncodeURIComponent (str) {
return encodeURIComponent(str).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
}
Solution 3:
As of Go 1.8, this situation has changed. We now have access to PathEscape
in addition to the older QueryEscape
to encode path components, along with the unescape counterpart PathUnescape
.
Solution 4:
For mimicking Javascript's encodeURIComponent()
, I created a string helper function.
Example: Turns "My String"
to "My%20String"
https://github.com/mrap/stringutil/blob/master/urlencode.go
import "net/url"
// UrlEncoded encodes a string like Javascript's encodeURIComponent()
func UrlEncoded(str string) (string, error) {
u, err := url.Parse(str)
if err != nil {
return "", err
}
return u.String(), nil
}
Solution 5:
How about this:
template.URLQueryEscaper(path)