求助,Golang Go语言中 http post 请求问题
求助,Golang Go语言中 http post 请求问题
期望结果:
- 正确获取 itop rest api 返回的工单数据
当我使用 Python 的 requests 库时,这一切都很正常,获取数据成功(如果我覆盖默认 headers,获取的结果如 golang 版本的一样。
这是 Python 的代码:
#!/usr/bin/python3
import requests, json
HOST = “http://192.168.17.22:8096/itop/webservices/rest.php?version=1.3”
json_str = json.dumps({
“operation”:
“core/get”,
“class”:
“UserRequest”,
“key”:
“SELECT UserRequest WHERE operational_status = ‘ongoing’”,
“output_fields”:
“request_type,servicesubcategory_name,urgency,origin,caller_id_friendlyname,impact,title,description”,
})
json_data = {
“auth_user”: “admin”,
“auth_pwd”: “goodjob@123”,
“json_data”: json_str
}
secure_rest_services
def get():
r = requests.post(HOST, data=json_data)
return r
if name == “main”:
result = get()
print(result.json())
输出
{'objects': {'UserRequest::7': {'code': 0, 'message': '', 'class': 'UserRequest', 'key': '7', 'fields': {'request_type': 'service_request', 'servicesubcategory_name': '钉钉权限开通', 'urgency': '4', 'origin': 'portal', 'caller_id_friendlyname': 'x 阿里合作项目负责人', 'impact': '1', 'title': '溫江|A-222|wb-xxxxxxxx', 'description': '<p>this is a test approve...</p>'}}, 'UserRequest::6': {'code': 0, 'message': '', 'class': 'UserRequest', 'key': '6', 'fields': {'request_type': 'service_request', 'servicesubcategory_name': '钉钉权限开通', 'urgency': '3', 'origin': 'portal', 'caller_id_friendlyname': 'x 阿里合作项目负责人', 'impact': '1', 'title': '成都|Xa-111|wb-xx111111', 'description': '<p>這是一個測試用的用戶需求</p>'}}}, 'code': 0, 'message': 'Found: 2'}
下面时 golang 版本的 post 请求
主函数:
package main
import (
“bytes”
“encoding/json”
“fmt”
“io/ioutil”
“log”
“net/http”
“strconv”
)
// 釘釘應用程序的 agentid
const (
ITOP_URL = http://192.168.17.22:8096/itop/webservices/rest.php?version=1.3
)
func main() {
request_auth := new(RequestAuth)
request_data := new(RequestData)
request_auth.AuthUser = “admin”
request_auth.AuthPwd = “goodjob@123”
request_data.Operation = "core/get"
request_data.Class = "UserRequest"
request_data.Key = "SELECT UserRequest WHERE operational_status = \"ongoing\""
request_data.OutPutFields = "request_type,servicesubcategory_name,urgency,origin,caller_id_friendlyname,impact,title,description"
req_data, err := json.Marshal(request_data)
if err != nil {
panic(err)
}
request_auth.JsonData = string(req_data)
jsonData, err := json.Marshal(request_auth)
if err != nil {
panic(err)
}
reader := bytes.NewReader(jsonData)
result := Post(ITOP_URL, reader)
fmt.Println(string(result))
}
func Post(url string, reader *bytes.Reader) []byte {
request, err := http.NewRequest(“POST”, url, reader)
if err != nil {
panic(err)
}
request.Header.Set(“Content-Type”, “application/json”)
request.Header.Set(“Content-Length”, strconv.Itoa(reader.Len()))
client := http.Client{}
resp, err := client.Do(request)
if err != nil {
log.Fatal(err.Error())
}
defer resp.Body.Close()
respBytes, _ := ioutil.ReadAll(resp.Body)
return respBytes
}
post 携带的数据模型
package main
// UserRequest structure
type Base struct {
Code int json:"code"
Message string json:"message"
}
type Fileds struct {
RequestType string json:"request_type"
ServiceSubcategoryName string json:"servicesubcategory_name"
Urgency string json:"urgency"
Origin string json:"origin"
CallerIdFriendlyName string json:"caller_id_friendlyname"
Impact string json:"impact"
Title string json:"title"
Description string json:"description"
}
type ResponseContent struct {
Code int json:"code"
Message string json:"message"
Class string json:"class"
Key string json:"key"
Filed Fileds json:"fields"
}
type Response struct {
Base
Object map[string]ResponseContent json:"objects"
}
// Request api data struct
type RequestData struct {
Operation string json:"operation"
Class string json:"class"
Key string json:"key"
OutPutFields string json:"output_fields"
}
type RequestAuth struct {
AuthUser string json:"auth_user"
AuthPwd string json:"auth_pwd"
// JsonData RequestData json:"json_data"
JsonData string json:"json_data"
}
输出:
{"code":5,"message":"Error: Missing parameter 'auth_user'"}
我猜这应该是 itop 需要 post 请求携带某个 header ?但我折腾了太久,直到实在没有办法才发帖求助。
求大佬们指点,(拜谢
更多关于求助,Golang Go语言中 http post 请求问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
jsonData, err := json.Marshal(request_auth)
把这里的 jsonData 打印出来 fmt.Println(string(jsonData )) 看是否包含 [auth_user]
更多关于求助,Golang Go语言中 http post 请求问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
json<br>{"auth_user":"admin","auth_pwd":"goodjob123","json_data":"{\"operation\":\"core/get\",\"class\":\"UserRequest\",\"key\":\"SELECT UserRequest WHERE operational_status = \\\"ongoing\\\"\",\"output_fields\":\"request_type,servicesubcategory_name,urgency,origin,caller_id_friendlyname,impact,title,description\"}"}<br>
wireshark 抓包看下发出去的是啥样的
我觉得是 json_data 内的字符串问题 二次 JSON 序列化 带上了很多\ 导致服务端对请求解析错误
hi,刚刚我抓包了一下,发送的值和 2 楼我发的一模一样,有可能像四楼说的那样。
如果是这样有什么推荐的解法吗
type RequestData struct {
Operation string json:"operation"
Class string json:"class"
Key string json:"key"
OutPutFields string json:"output_fields"
}
type RequestAuth struct {
AuthUser string json:"auth_user"
AuthPwd string json:"auth_pwd"
// JsonData RequestData json:"json_data"
JsonData RequestData json:"json_data"
}
不需要二次序列化
你的服务器接收的 post 请求,是 form data 格式的吧,不是 json 吧。
r = requests.post(HOST, data=json_data)
同意楼上,post 默认的 content-type 应该是"application/x-www-form-unlencoded"
py 里,如果想发送 json 数据,正确的方法是:<br>r = requests .post(HOST, data=json_dump(json_data))<br>
或者<br>r = requests .post(HOST, json=json_data)<br>
既然你的 py 代码能正常工作,则表明服务端把你的 post 请求,以 formdata 格式处理
我猜是这样,requests 的 data 参数发出去是 form,a=b&c=d 样式的,不是 json,而你 golang 的代码是用 json 发出去的
用 url.Values 试试好了。
所以,应该使用 url.Values 去存你的那些数据,然后将 Encode 之后的数据当做 body,post 出去。
具体可以搜索:golang post form urlencoded
感谢几位的回复,解决了困扰我一天的难题,非常感谢。
你好!
关于你在 Golang 中遇到的 HTTP POST 请求问题,以下是一些可能的解决步骤和建议:
-
检查请求 URL 和端口: 确保你发送 POST 请求的 URL 和端口是正确的。如果 URL 有误或端口未开放,会导致请求失败。
-
设置请求头: POST 请求通常需要设置正确的
Content-Type
请求头。例如,如果你发送 JSON 数据,应该设置Content-Type: application/json
。 -
构建请求体: 根据
Content-Type
,确保请求体的格式正确。对于 JSON 数据,可以使用json.Marshal
方法将结构体或 map 转换为 JSON 格式的字节数组。 -
处理响应: 发送请求后,要检查响应的状态码和响应体。如果状态码不是 2xx,说明请求未成功,可以根据响应体中的错误信息进一步调试。
-
错误处理: 在发送请求和处理响应的过程中,加入适当的错误处理逻辑,以便在出现问题时能够捕获并处理错误。
-
使用工具调试: 使用 Postman 或 curl 等工具测试相同的 POST 请求,看是否能成功。这有助于确定问题是出在 Go 代码上,还是服务器端的问题。
如果以上步骤仍未解决问题,请提供更详细的错误信息(如完整的错误日志和代码片段),以便进一步分析。希望这些信息对你有所帮助!