如何在Golang中构建URL /查询

huangapple go评论72阅读模式
英文:

How to build a URL / Query in Golang

问题

背景 -

我需要根据用户在表单中输入的内容构建一个基于URL/查询的API调用。

问题 -

在构建URL时,参数没有被正确转义。例如,查询"bad santa"最终会出现空格而不是"+"。

当前输出 -

例如:https://api.example.org/3/search/movie?query=bad
santa&api_key=#######

期望输出 -

例如:https://api.example.org/3/search/movie?query=bad+santa&api_key=#######

代码示例 -

根URL -

var SearchUrl = "https://www.example.org/3/search/movie?query="

从用户输入中获取参数 -

var MovieSearch []string = r.Form["GetSearchKey"]

API密钥 -

var apiKey = "&api_key=######"

我使用ArrayToString()函数来解析表单输入数据

func ArrayToString(array []string) string{
    str := strings.Join(array, "+")
    return str
}

然后构建URL -

var SearchUrl = "https://api.example.org/3/search/movie?query="
var MovieSearch []string = r.Form["GetSearchKey"]
var apiKey = "&api_key=########"
UrlBuild := []string {SearchUrl, ArrayToString(MovieSearch), apiKey}
OUTPUT_STRING := ArrayToString(UrlBuild)

问题 -

如何正确转义用户输入的GET参数来构建URL?

英文:

Background -

I need to build a URL / query based on user input from a form that will be used to make an API call.

Problem -

When building the URL, the params are not properly escaped. For example, the query "bad santa" ends up with a space between it instead of "+".

Current Output -
> e.g. https://api.example.org/3/search/movie?query=bad
> santa&api_key=#######

Expected Output -
> e.g. https://api.example.org/3/search/movie?query=bad+santa&api_key=#######

Code Example -

Root URL -

var SearchUrl = "https://www.example.org/3/search/movie?query="

Get params taken from user input -

var MovieSearch []string = r.Form["GetSearchKey"]  

API Key -

var apiKey = "&api_key=######"

I am using the ArrayToString() to parse the form input data

func ArrayToString(array []string) string{
    str := strings.Join(array, "+")
    return str 
}

Then building the URL -

var SearchUrl = "https://api.example.org/3/search/movie?query="
var MovieSearch []string = r.Form["GetSearchKey"]  
var apiKey = "&api_key=########"
UrlBuild := []string {SearchUrl, ArrayToString(MovieSearch), apiKey}
OUTPUT_STRING := ArrayToString(UrlBuild)

Question -

How to build a URL with user input GET params that are escaped properly?

答案1

得分: 8

通常,应该使用url包的Values功能。

以下是一个示例,它可以实现你想要的功能,请点击此处查看示例。示例包括一个简单的main函数和一个http.HandlerFunc形式的处理函数:

package main

import "fmt"
import "net/url"
import "net/http"

func main() {
    baseURL := "https://www.example.org/3/search/movie"
    v := url.Values{}
    v.Set("query", "this is a value")
    perform := baseURL + "?" + v.Encode()
    fmt.Println("Perform:", perform)
}

func formHandler(w http.ResponseWriter, r *http.Request) {
    baseURL := "https://www.example.org/3/search/movie"
    v := url.Values{}
    
    v.Set("query", r.Form.Get("GetSearchKey")) // 从提交的表单中获取GetSearchKey的值
    v.Set("api_key", "YOURKEY") // 替换为你的API密钥
    
    perform := baseURL + "?" + v.Encode() // 组合URL
    fmt.Println("Perform:", perform) // 对其进行操作
}

输出结果为:
Perform: https://www.example.org/3/search/movie?query=this+is+a+value

请注意,值已经正确地转义并放入查询字符串中。

英文:

Normally, one should use url package's Values.

Here's an example, that does what I think you want, on play
Both a simple main, and in http.HandlerFunc form:

package main

import "fmt"
import "net/url"
import "net/http"

func main() {
	baseURL := "https://www.example.org/3/search/movie"
	v := url.Values{}
	v.Set("query", "this is a value")
	perform := baseURL + "?" + v.Encode()
	fmt.Println("Perform:", perform)
}

func formHandler(w http.ResponseWriter, r *http.Request) {
	baseURL := "https://www.example.org/3/search/movie"
	v := url.Values{}
	
	v.Set("query", r.Form.Get("GetSearchKey")) // take GetSearchKey from submitted form
	v.Set("api_ley", "YOURKEY") // whatever your api key is
	
	perform := baseURL + "?" + v.Encode() // put it all together
	fmt.Println("Perform:", perform) // do something with it
}

Output:
Perform: https://www.example.org/3/search/movie?query=this+is+a+value

Notice how the values are put in to query string, properly escaped, for you.

答案2

得分: 3

你可以使用https://golang.org/pkg/net/url/#QueryEscape来转义参数,而不是自己手动处理。

此外,你应该使用https://golang.org/pkg/net/url/#URL来构建你的URL:

params := fmt.Sprintf("?query=%s&api_key=######", url.QueryEscape("name"))
perform := url.URL{
    Scheme:   "https",
    Host:     "api.example.com",
    Path:     "3/search/movie",
    RawQuery: params,
}

fmt.Println(perform) // <- 调用 .String()

我建议你查看https://golang.org/doc/effective_go.html。

如果你的数据是一个 []string:

func ArrayToQuery(values []string) string {
    return url.QueryEscape(strings.Join(values, " "))
}
英文:

You can escape parameters using https://golang.org/pkg/net/url/#QueryEscape, instead of doing it yourself.

Besides you should be using https://golang.org/pkg/net/url/#URL to build up your url:

params := fmt.Sprintf(&quot;?query=%s&amp;api_key=######&quot;, url.QueryEscape(&quot;name&quot;))
perform := url.URL{
	Scheme: 	&quot;https&quot;,  
    Host: 		&quot;api.example.com&quot;,
    Path:		&quot;3/search/movie&quot;,
    RawQuery: 	params,
}

fmt.Println(perform) // &lt;- Calls .String()

I recommend to check https://golang.org/doc/effective_go.html.

If your data comes in []string:

func ArrayToQuery(values []string) string {
	return url.QueryEscape(strings.Join(values, &quot; &quot;))
}

答案3

得分: 0

如果MovieSearch包含一个值为"bad santa"的元素,你所看到的是正确的。它将这三个字符串连接起来,并在它们之间放置"+".

英文:

If MovieSearch contains one element with the value "bad santa", what you're seeing looks correct. It's joining those three strings and putting "+" between them.

答案4

得分: -1

如果单词中有空格,你需要将其替换。

示例:

package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println(strings.Replace("bad santa", " ", "+", -1))
}

所以你应该像这样做:

func main() {
    a := []string{"bad", "santa"}
    fmt.Printf("%q\n", a)
    j := ArrayToString(a)
    strings.Replace(j, " ", "+",-1)
    fmt.Printf("%q\n", j)
}

这是Go文档的链接- https://golang.org/pkg/strings/#Replace

英文:

If there is a space in the word you will need to replace it.

Example

package main

import (
	&quot;fmt&quot;
	&quot;strings&quot;
)

func main() {
	fmt.Println(strings.Replace(&quot;bad santa&quot;, &quot; &quot;, &quot;+&quot;, -1))
}

So you should probably do it like this

func main() {
    a := []string{&quot;bad&quot;, &quot;santa&quot;}
    fmt.Printf(&quot;%q\n&quot;, a)
    j := ArrayToString(a)
    strings.Replace(j, &quot; &quot;, &quot;+&quot;,-1)
    fmt.Printf(&quot;%q\n&quot;, j)
}

Here is a link to the Go Documentation - https://golang.org/pkg/strings/#Replace

huangapple
  • 本文由 发表于 2016年3月14日 10:26:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/35978605.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定