大发龙虎稳赢首页    注册   登录
大发龙虎稳赢 = way to explore
大发龙虎稳赢 是一个大发龙虎稳赢关于 分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
beego
Aumujun
大发龙虎稳赢  ›  Go

求助, golang http post 请求问题

  •  
  •   Aumujun · 14 天前 · 1211 次点击

    期望结果:

    • 正确获取 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": "[email protected]",
        "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 = "[email protected]"
    
    	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 ?但大发龙虎稳赢我 折腾了太久,直到实在没有办法才发帖求助。

    求大佬们指点,(拜谢

    12 回复  |  直到 2020-01-14 18:48:19 +08:00
    BlackBerry999
        1
    BlackBerry999   14 天前
    jsonData, err := json.Marshal(request_auth)
    把这里的 jsonData 打印出来 fmt.Println(string(jsonData )) 看是否包含 [auth_user]
    Aumujun
        2
    Aumujun   14 天前
    @BlackBerry999

    ```json
    {"auth_user":"admin","auth_pwd":"[email protected]","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\"}"}
    ```
    virusdefender
        3
    virusdefender   14 天前
    wireshark 抓包看下发出去的是啥样的
    BlackBerry999
        4
    BlackBerry999   14 天前
    @Aumujun 大发龙虎稳赢我 觉得是 json_data 内的字符串问题 二次 JSON 序列化 带上了很多\ 导致大发龙虎稳赢服务 端对请求解析错误
    Aumujun
        5
    Aumujun   14 天前
    @virusdefender hi,刚刚大发龙虎稳赢我 抓包了一下,发送的值和 2 楼大发龙虎稳赢我 发的一模一样,有可能像四楼说的那样。

    @BlackBerry999 如果是这样有什么大发龙虎稳赢推荐 的解法吗
    useben
        6
    useben   14 天前
    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"`
    }

    不需要二次序列化
    index90
        7
    index90   14 天前
    大发龙虎稳赢你 的大发龙虎稳赢服务 器接收的 post 请求,是 form data 格式的吧,不是 json 吧。
    r = requests.post(HOST, data=json_data)
    kidtest
        8
    kidtest   14 天前
    同意楼上,post 默认的 content-type 应该是"application/x-www-form-unlencoded"
    index90
        9
    index90   14 天前
    py 里,如果想发送 json 数据,正确的大发龙虎稳赢方法 是:
    ```
    r = requests .post(HOST, data=json_dump(json_data))
    ```
    或者
    ```
    r = requests .post(HOST, json=json_data)
    ```
    既然大发龙虎稳赢你 的 py 代码能正常工作,则表明大发龙虎稳赢服务 端把大发龙虎稳赢你 的 post 请求,以 formdata 格式处理
    Vegetable
        10
    Vegetable   14 天前
    @index90 大发龙虎稳赢我 猜是这样,requests 的 data 参数发出去是 form,a=b&c=d 样式的,不是 json,而大发龙虎稳赢你 golang 的代码是用 json 发出去的
    用 url.Values 试试好了。
    kidtest
        11
    kidtest   14 天前
    @kidtest
    所以,应该使用 url.Values 去存大发龙虎稳赢你 的那些数据,然后将 Encode 之后的数据当做 body,post 出去。
    具体可以大发龙虎稳赢搜索 :golang post form urlencoded
    Aumujun
        12
    Aumujun   14 天前
    @index90
    @Vegetable
    @kidtest

    感谢几位的回复,解决了困扰大发龙虎稳赢我 一天的难题,非常感谢。
    大发龙虎稳赢关于   ·   FAQ   ·   API   ·   大发龙虎稳赢大发龙虎稳赢我 们 的愿景   ·   广告投放   ·   感谢   ·   实用小大发龙虎稳赢工具   ·   835 人在线   最高记录 5168   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 21ms · UTC 22:42 · PVG 06:42 · LAX 14:42 · JFK 17:42
    ♥ Do have faith in what you're doing.