{"id":33281017,"url":"https://github.com/wangluozhe/requests","last_synced_at":"2025-11-17T13:00:41.428Z","repository":{"id":37885278,"uuid":"464366335","full_name":"wangluozhe/requests","owner":"wangluozhe","description":"用于快速请求HTTP或HTTPS，并支持修改ja3、ja4指纹","archived":false,"fork":false,"pushed_at":"2025-11-13T10:32:44.000Z","size":1068,"stargazers_count":545,"open_issues_count":21,"forks_count":115,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-11-13T12:18:57.675Z","etag":null,"topics":["go","golang","http","http2","https","ja3","ja4","request","requests"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wangluozhe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-02-28T06:35:01.000Z","updated_at":"2025-11-13T10:32:48.000Z","dependencies_parsed_at":"2023-12-21T15:19:38.936Z","dependency_job_id":"b017ccab-dcba-4a63-8eed-1a123b941660","html_url":"https://github.com/wangluozhe/requests","commit_stats":null,"previous_names":[],"tags_count":39,"template":false,"template_full_name":null,"purl":"pkg:github/wangluozhe/requests","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wangluozhe%2Frequests","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wangluozhe%2Frequests/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wangluozhe%2Frequests/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wangluozhe%2Frequests/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wangluozhe","download_url":"https://codeload.github.com/wangluozhe/requests/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wangluozhe%2Frequests/sbom","scorecard":{"id":113578,"data":{"date":"2025-08-04","repo":{"name":"github.com/wangluozhe/requests","commit":"95dc5240488a52f2dec9dbf1803a8036b15cfde9"},"scorecard":{"version":"v5.2.1-28-gc1d103a9","commit":"c1d103a9bb9f635ec7260bf9aa0699466fa4be0e"},"score":4,"checks":[{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#packaging"}},{"name":"Maintained","score":7,"reason":"1 commit(s) and 8 issue activity found in the last 90 days -- score normalized to 7","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#maintained"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#sast"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: GNU General Public License v3.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#license"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#signed-releases"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-15T19:29:28.868Z","repository_id":37885278,"created_at":"2025-08-15T19:29:28.868Z","updated_at":"2025-08-15T19:29:28.868Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":284885669,"owners_count":27079125,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-17T02:00:06.431Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","http","http2","https","ja3","ja4","request","requests"],"created_at":"2025-11-17T13:00:21.749Z","updated_at":"2025-11-17T13:00:41.421Z","avatar_url":"https://github.com/wangluozhe.png","language":"Go","readme":"# requests\n[![Gitee link address](https://img.shields.io/badge/gitee-reference-red?logo=gitee\u0026logoColor=red\u0026labelColor=white)](https://gitee.com/leegene/requests)[![Github link address](https://img.shields.io/badge/github-reference-blue?logo=github\u0026logoColor=black\u0026labelColor=white\u0026color=black)](https://github.com/wangluozhe/requests)[![Go Version](https://img.shields.io/badge/Go%20Version-1.24.0-blue?logo=go\u0026logoColor=white\u0026labelColor=gray)]()[![Release Version](https://img.shields.io/badge/release-v1.4.7-blue)]()[![go documentation](https://img.shields.io/badge/go-documentation-blue)](https://pkg.go.dev/github.com/wangluozhe/requests)[![license GPL-3.0](https://img.shields.io/badge/license-GPL3.0-orange)](https://github.com/wangluozhe/requests/blob/main/LICENSE)\n\nrequests支持以下新特性：\n\n1. 支持http2，默认以http2进行连接，连接失败后会进行退化而进行http1.1连接\n2. 支持JA3指纹修改\n3. 支持http2+JA3指纹\n4. 支持修改TLS指纹\n5. 支持修改http2指纹\n\n**此模块参考于Python的[requests模块](https://github.com/psf/requests/tree/main/requests)**\n\n\n## 加入微信群聊\n如果你想跟更多志同道合的人一起学习，那么加入群聊来吧！(备注：加群)\n![微信群聊](./imgs/wechat.jpg)\n\n\n## 下载requests库\n\n```bash\ngo get github.com/wangluozhe/requests\n```\n\n\n\n## 下载指定版\n\n```bash\ngo get github.com/wangluozhe/requests@v1.4.7\n```\n\n\n\n# 快速上手\n\n迫不及待了吗？本页内容为如何入门 Requests 提供了很好的指引。其假设你已经安装了 Requests。如果还没有，去安装看看吧。\n\n首先，确认一下：\n\n- Requests已安装\n- Requests是最新的\n\n让我们从一些简单的示例开始吧。\n\n\n\n## 发送请求\n\n使用 requests 发送网络请求非常简单。\n\n一开始要导入requests 模块：\n\n```go\nimport (\n    \"github.com/wangluozhe/requests\"\n    \"github.com/wangluozhe/requests/url\"\n)\n```\n\n然后，尝试获取某个网页。本例子中，我们来获取 Github 的公共时间线：\n\n```go\nr, err := requests.Get(\"https://api.github.com/events\", nil)\n```\n\n现在，我们有一个名为 `r` 的 [`Response`](https://docs.python-requests.org/zh_CN/latest/api.html#requests.Response) 对象。我们可以从这个对象中获取所有我们想要的信息。\n\nRequests 简便的 API 意味着所有 HTTP 请求类型都是显而易见的。例如，你可以这样发送一个 HTTP POST 请求：\n\n```go\ndata := url.NewData()\ndata.Set(\"key\",\"value\")\nr, err := requests.Post(\"http://httpbin.org/post\", \u0026url.Request{Data: data})\n```\n\n漂亮，对吧？那么其他 HTTP 请求类型：PUT，DELETE，HEAD 以及 OPTIONS 又是如何的呢？都是一样的简单：\n\n```go\ndata := url.NewData()\ndata.Set(\"key\",\"value\")\nr, err := requests.Post(\"http://httpbin.org/post\", \u0026url.Request{Data: data})\nr, err = requests.Delete(\"http://httpbin.org/delete\")\nr, err = requests.Head(\"http://httpbin.org/get\")\nr, err = requests.Options(\"http://httpbin.org/get\")\n```\n\n都很不错吧，但这也仅是 requests 的冰山一角呢。\n\n\n\n## 设置代理\n\nrequests设置代理也非常简单，只需给req.Proxies传入代理ip即可。\n\n```go\nreq := url.NewRequest()\nreq.Proxies = \"http://127.0.0.1:32768\"\n// 设置带账号密码的代理：req.Proxies = \"http://username:password@ip:port\"\n\nr, err := requests.Get(\"https://api.github.com/events\", req)\n```\n\n\n\n## 传递 URL 参数\n\n你也许经常想为 URL 的查询字符串(query string)传递某种数据。如果你是手工构建 URL，那么数据会以键/值对的形式置于 URL 中，跟在一个问号的后面。例如， `httpbin.org/get?key=val`。 Requests 允许你使用 `params` 关键字参数，以一个字符串字典来提供这些参数。举例来说，如果你想传递 `key1=value1` 和 `key2=value2` 到 `httpbin.org/get` ，那么你可以使用如下代码：\n\n```go\nparams := url.NewParams()\nparams.Set(\"key1\",\"value1\")\nparams.Set(\"key2\",\"value2\")\nr, err := requests.Get(\"http://httpbin.org/get\",\u0026url.Request{Params: params})\nif err != nil {\n\tfmt.Println(err)\n}\n```\n\n或者：\n\n```golang\n// map[string]type，type = string|int|float64|interface{}|[]string|[]int|[]float64|[]interface{}\nreq := url.NewRequest()\n//params := map[string]string{\n//\t\"page\":  \"1\",\n//\t\"limit\": \"20\",\n//\t\"skip\":  \"5\",\n//}\n//params := map[string]int{\n//\t\"page\":  1,\n//\t\"limit\": 20,\n//\t\"skip\":  5,\n//}\n//params := map[string][]string{\n//\t\"page\":  []string{\"1\", \"2\"},\n//\t\"limit\": []string{\"20\"},\n//\t\"skip\":  []string{\"5\"},\n//}\n//params := map[string][]int{\n//\t\"page\":  []int{1, 2},\n//\t\"limit\": []int{20},\n//\t\"skip\":  []int{5},\n//}\nparams := map[string]interface{}{\n    \"page\":  []interface{}{\"1\", 2},\n    \"limit\": []string{\"20\"},\n    \"skip\":  []int{5},\n}\nreq.Params = url.ParseParams(params)\nr, err := requests.Get(\"https://httpbin.org/get\", req)\nif err != nil {\n    fmt.Println(err)\n}\nfmt.Println(r.Text)\n```\n\n或者：\n\n```go\nparams := url.ParseParams(\"key1=value1\u0026key2=value2\")\nr, err := requests.Get(\"http://httpbin.org/get\",\u0026url.Request{Params: params})\nif err != nil {\n\tfmt.Println(err)\n}\n```\n\n通过打印输出该 URL，你能看到 URL 已被正确编码：\n\n```go\nfmt.Println(r.Url)\nhttp://httpbin.org/get?key1=value1\u0026key2=value2\n```\n\n你还可以使Params有多个值传入：\n\n```go\nparams := url.NewParams()\nparams.Set(\"key1\",\"value1\")\nparams.Add(\"key1\",\"value2\")\nparams.Set(\"key2\",\"value2\")\nr, err := requests.Get(\"http://httpbin.org/get\",\u0026url.Request{Params: params})\nif err != nil {\n\tfmt.Println(err)\n}\nfmt.Println(r.Url)\n\nhttp://httpbin.org/post?key1=value1\u0026key1=value2\u0026key2=value2\n```\n\n\n\n## 响应内容\n\n我们能读取服务器响应的内容。再次以 GitHub 时间线为例：\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wangluozhe/requests\"\n)\n\nfunc main() {\n\tr, err := requests.Get(\"https://api.github.com/events\", nil)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\tfmt.Println(r.Text)\n}\n\n[{\"repository\":{\"open_issues\":0, \"url\":\"https://github.com/...\n```\n\nrequests 会自动解码来自服务器的内容。大多数 unicode 字符集都能被无缝地解码。\n\n\n\n## 二进制响应内容\n\n你也能以字节数组的方式访问请求响应体，对于非文本请求：\n\n```go\nfmt.Println(r.Content)\n[91 123 34 105 100 34 58 34 50 48 55 49 52 50 51 57 56 48 53 34 44 34 116 121 112 101 34 58 34...\n```\n\nRequests 会自动为你解码 `gzip` 和 `deflate` 以及`br`传输编码的响应数据。\n\n例如，以请求返回的二进制数据创建一张图片，你可以使用如下代码：\n\n```go\npackage main\n\nimport \"github.com/wangluozhe/requests\"\n\nfunc main(){\n    r, err := requests.Get(\"图片URL\", nil)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\tjpg,_ := os.Create(\"1.jpg\")\n\tio.Copy(jpg,r.Body)\t\t// 第一种\n\t//jpg.Write(resp.Content)\t// 第二种\n}\n```\n\n\n\n## JSON 响应内容\n\nRequests 中也有一个内置的 JSON 解码器，助你处理 JSON 数据（或者使用第三方库[go-simplejson](https://github.com/bitly/go-simplejson)）：\n\n[go-simplejson文档](https://pkg.go.dev/github.com/bitly/go-simplejson)\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wangluozhe/requests\"\n)\n\nfunc main(){\n    r, err := requests.Get(\"https://api.github.com/events\", nil)\n    if err != nil{\n    \tfmt.Println(err)\n    }\n    json, err := r.Json() // 推荐使用r.SimpleJson，自带的json解码使用太过于复杂\n    // json, err := r.SimpleJson()\n    fmt.Println(json, err)\n}\n\n{\"Accept-Ranges\":[\"bytes\"],\"Access-Control-Allow-Origin\":[\"*\"],\"Access-Control...\n```\n\n如果 JSON 解码失败， `r.Json()` 就会返回一个异常。例如，响应内容是 401 (Unauthorized)，尝试访问 `r.Json()` 将会抛出 `map[] invalid character '(' after top-level value` 异常。\n\n需要注意的是，成功调用 `r.Json()` 并**不**意味着响应的成功。有的服务器会在失败的响应中包含一个 JSON 对象（比如 HTTP 500 的错误细节）。这种 JSON 会被解码返回。要检查请求是否成功，请检查 `r.StatusCode` 是否和你的期望相同。\n\n\n\n## 原始响应内容\n\n在罕见的情况下，你可能想获取来自服务器的原始套接字响应，那么你可以访问 `r.Body`。 具体你可以这么做：\n\n```go\nr, err := requests.Get(\"http://www.baidu.com\", nil)\nif err != nil {\n    fmt.Println(err)\n}\nfmt.Println(r.Body)\n\n// 返回的是io.ReadCloser类型\n```\n\n但一般情况下，你应该以下面的模式将文本流保存到文件：\n\n```go\nf, _ := os.Create(\"baidu.txt\")\nio.Copy(f,r.Body)\n```\n\n\n\n## 定制请求头\n\n如果你想为请求添加 HTTP 头部，只要简单地`url.NewHeaders()` 给 `Headers` 参数就可以了。\n\n例如，在前一个示例中我们没有指定 content-type:\n\n```go\nrawurl := \"https://api.github.com/some/endpoint\"\nheaders := url.NewHeaders()\nheaders.Set(\"user-agent\", \"my-app/0.0.1\")\nreq := url.NewRequest()\nreq.Headers = headers\n\nr, err := requests.Get(rawurl, req)\n```\n或者\n```go\nrawurl := \"https://api.github.com/some/endpoint\"\nreq := url.NewRequest()\nreq.Headers = url.ParseHeaders(map[string]interface{}{\n    \":authority\":                \"spidertools.cn\",\n    \":method\":                   \"GET\",\n    \":path\":                     \"/\",\n    \":scheme\":                   \"https\",\n    \"accept\":                    \"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\",\n    \"accept-encoding\":           \"gzip, deflate, br\",\n    \"accept-language\":           \"zh-CN,zh;q=0.9\",\n    \"cache-control\":             \"no-cache\",\n    \"cookie\":                    \"_ga=GA1.1.630251354.1645893020; Hm_lvt_def79de877408c7bd826e49b694147bc=1647245863,1647936048,1648296630; Hm_lpvt_def79de877408c7bd826e49b694147bc=1648296630\",\n    \"pragma\":                    \"no-cache\",\n    \"sec-ch-ua\":                 \"\\\" Not A;Brand\\\";v=\\\"99\\\", \\\"Chromium\\\";v=\\\"98\\\", \\\"Google Chrome\\\";v=\\\"98\\\"\",\n    \"sec-ch-ua-mobile\":          \"?0\",\n    \"sec-ch-ua-platform\":        \"\\\"Windows\\\"\",\n    \"sec-fetch-dest\":            \"document\",\n    \"sec-fetch-mode\":            \"navigate\",\n    \"sec-fetch-site\":            \"same-origin\",\n    \"sec-fetch-user\":            \"?1\",\n    \"upgrade-insecure-requests\": \"1\",\n    \"user-agent\":                \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36\",\n}) // 注意：此方式生成的headers是无序的，因为map是无序的。\nr, err := requests.Get(rawurl, req)\n```\n\n注意: 定制 header 的优先级低于某些特定的信息源，例如：\n\n- `Content-Length`请求头不能随便设置，可能会有错误发生。\n- 如果被重定向到别的主机，授权 header 就会被删除。\n- 代理授权 header 会被 URL 中提供的代理身份覆盖掉。\n- 在我们能判断内容长度的情况下，header 的 Content-Length 会被改写。\n\n更进一步讲，Requests 不会基于定制 header 的具体情况改变自己的行为。只不过在最后的请求中，所有的 header 信息都会被传递进去。\n\n注意: 所有的 header 值必须是 `string`。\n\n\n\n## 有序请求头\n\n如果你想让你的请求头变为有序的话，请添加一个`\"Header-Order:\"`参数即可，值为有序请求头数组，注：值必须全部为小写。\n\n例如：\n\n```go\npackage main\n\nimport (\n\t\"github.com/wangluozhe/requests/url\"\n)\n\nfunc main(){\n    headers := url.NewHeaders()\n    headers.Set(\"Path\", \"/get\")\n    headers.Set(\"User-Agent\", \"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36\")\n    headers.Set(\"accept-language\", \"zh-CN,zh;q=0.9\")\n    headers.Set(\"Scheme\", \"https\")\n    headers.Set(\"accept-encoding\", \"gzip, deflate, br\")\n    //headers.Set(\"Content-Length\", \"100\")\t// 注意，不能随便改变Content-Length大小\n    headers.Set(\"Host\", \"httpbin.org\")\n    headers.Set(\"Accept\", \"application/json, text/javascript, */*; q=0.01\")\n    (*headers)[\"Header-Order:\"] = []string{\t// 请求头排序，值必须为小写\n        \"user-agent\",\n        \"path\",\n        \"accept-language\",\n        \"scheme\",\n        \"connection\",\n        \"accept-encoding\",\n        \"content-length\",\n        \"host\",\n        \"accept\",\n    }\n    req.Headers = headers\n    r, err := requests.Get(\"https://httpbin.org/get\", req)\n    if err != nil {\n        fmt.Println(err)\n    }\n    fmt.Println(\"text:\", r.Text)\n\n    // 最好用fiddler抓包工具查看一下\n}\n```\n\n或者：\n\n```go\npackage main\n\nimport (\n\t\"github.com/wangluozhe/requests/url\"\n)\n\nfunc main(){\n    req := url.NewRequest()\n    req.Headers = url.ParseHeaders(`\n    :authority: spidertools.cn\n    :method: GET\n    :path: /\n    :scheme: https // 不会被加入到头部中\n    // accept: text/html // 不会被加入到头部中，因为被注释了\n    accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\n    accept-encoding: gzip, deflate, br\n    accept-language: zh-CN,zh;q=0.9\n    cache-control: no-cache\n    cookie: _ga=GA1.1.630251354.1645893020; Hm_lvt_def79de877408c7bd826e49b694147bc=1647245863,1647936048,1648296630; Hm_lpvt_def79de877408c7bd826e49b694147bc=1648296630\n    pragma: no-cache\n    sec-ch-ua: \" Not A;Brand\";v=\"99\", \"Chromium\";v=\"98\", \"Google Chrome\";v=\"98\"\n    sec-ch-ua-mobile: ?0\n    sec-ch-ua-platform: \"Windows\"\n    sec-fetch-dest: document\n    sec-fetch-mode: navigate\n    sec-fetch-site: same-origin\n    sec-fetch-user: ?1\n    upgrade-insecure-requests: 1\n    user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.80 Safari/537.36\n    `) // 注意：这是反引号，不是单引号\n    r, err := requests.Get(\"https://httpbin.org/get\", req)\n    if err != nil {\n        fmt.Println(err)\n    }\n    fmt.Println(\"text:\", r.Text)\n\n    // 最好用fiddler抓包工具查看一下\n}\n```\n\n\n\n## 更加复杂的 POST 请求\n\n通常，你想要发送一些编码为表单形式的数据——非常像一个 HTML 表单。要实现这个，只需简单地`url.NewData()`给 `Data` 参数。你的数据字典在发出请求时会自动编码为表单形式：\n\n```go\ndata := url.NewData()\ndata.Set(\"key1\",\"value1\")\ndata.Set(\"key2\",\"value2\")\n\nreq := url.NewRequest()\nreq.Data = data\nr, err := requests.Post(\"http://www.baidu.com\",req)\nif err != nil {\n    fmt.Println(err)\n}\n\nfmt.Println(r.Text)\n\n...\n\"form\": {\n    \"key1\": \"value1\", \n    \"key2\": \"value2\"\n}\n...\n```\n\n或者：\n\n```go\nreq := url.NewRequest()\n// 跟url.ParseParams同一用法，只是名称不同而已。\n// data := map[string]interface{}{\n//    \"page\":  []interface{}{\"1\", 2},\n//    \"limit\": []string{\"20\"},\n//    \"skip\":  []int{5},\n// }\n// req.Data = url.ParseData(data)\nreq.Data = url.ParseData(\"key1=value1\u0026key2=value2\")\nr, err := requests.Post(\"http://www.baidu.com\",req)\nif err != nil {\n    fmt.Println(err)\n}\n\nfmt.Println(r.Text)\n\n...\n\"form\": {\n    \"key1\": \"value1\", \n    \"key2\": \"value2\"\n}\n...\n```\n\n你还可以为 `data`在表单中多个元素使用同一 key 的时候，这种方式尤其有效：\n\n```go\ndata := url.NewData()\ndata.Set(\"key1\",\"value1\")\ndata.Add(\"key1\",\"value3\")\ndata.Set(\"key2\",\"value2\")\ndata.Add(\"key2\",\"value4\")\n\nreq := url.NewRequest()\nreq.Data = data\nr, err := requests.Post(\"http://httpbin.org/post\",req)\nif err != nil {\n    fmt.Println(err)\n}\nfmt.Println(r.Text)\n\n...\n\"form\": {\n    \"key1\": [\n      \"value1\", \n      \"value3\"\n    ], \n    \"key2\": [\n      \"value2\", \n      \"value4\"\n    ]\n}\n...\n```\n\n很多时候你想要发送的数据并非编码为表单形式的。如果你想传递一个 `json` 数据那么用下面的方法。\n\n你可以使用 `Json` 参数直接传递，然后它就会被自动编码。\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wangluozhe/requests\"\n\t\"github.com/wangluozhe/requests/url\"\n)\n\nfunc main() {\n\treq := url.NewRequest()\n\treq.Json = map[string]interface{}{ // 修正老版map[string]string\n\t\t\"some\":   \"data\",\n\t\t\"name\":   \"测试\",\n\t\t\"colors\": []string{\"蓝色\", \"绿色\", \"紫色\"},\n\t\t\"data\": map[string]interface{}{\n\t\t\t\"json\": true,\n\t\t\t\"age\":  15,\n\t\t},\n\t}\n\tr, err := requests.Post(\"http://httpbin.org/post\", req)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\tfmt.Println(r.Text)\n}\n\n{\n  \"args\": {}, \n  \"data\": \"{\\\"colors\\\":[\\\"\\u84dd\\u8272\\\",\\\"\\u7eff\\u8272\\\",\\\"\\u7d2b\\u8272\\\"],\\\"data\\\":{\\\"age\\\":15,\\\"json\\\":true},\\\"name\\\":\\\"\\u6d4b\\u8bd5\\\",\\\"some\\\":\\\"data\\\"}\", \n  \"files\": {}, \n  \"form\": {}, \n  \"headers\": {\n    \"Accept\": \"*/*\", \n    \"Accept-Encoding\": \"gzip, deflate, br\", \n    \"Content-Length\": \"99\", \n    \"Content-Type\": \"application/json\", \n    \"Host\": \"httpbin.org\", \n    \"User-Agent\": \"golang-requests 1.0\", \n    \"X-Amzn-Trace-Id\": \"Root=1-6241ac54-4345fed071127ed54d2ae83b\"\n  }, \n  \"json\": {\n    \"colors\": [\n      \"\\u84dd\\u8272\", \n      \"\\u7eff\\u8272\", \n      \"\\u7d2b\\u8272\"\n    ], \n    \"data\": {\n      \"age\": 15, \n      \"json\": true\n    }, \n    \"name\": \"\\u6d4b\\u8bd5\", \n    \"some\": \"data\"\n  }, \n  \"origin\": \"220.249.16.210\", \n  \"url\": \"http://httpbin.org/post\"\n}\n```\n\n\n\n## POST一个多部分编码(Multipart-Encoded)的文件或FormData\n\nrequests 使得上传多部分编码文件变得很简单：\n\n```go\nfiles := url.NewFiles()\n// SetFile(name,fileName,filePath,contentType)\n// name为字段名，fileName为上传的文件名，filePath为上传文件的绝对路径，contentType为上传的文件类型\n// 如果contentType设置为\"\"，则默认为\"application/octet-stream\"\nfiles.SetFile(\"api\",\"api\",\"D:\\\\Go\\\\github.com\\\\wangluozhe\\\\requests\\\\api.go\",\"\")\nreq := url.NewRequest()\nreq.Files = files\nr, err := requests.Post(\"http://httpbin.org/post\",req)\nif err != nil {\n    fmt.Println(err)\n}\nfmt.Println(r.Text)\n\n...\n\"files\": {\n    \"api\": \"文件内容\"\n}\n...\n```\n\nrequests使得FormData的使用也方便多了：\n\n```go\nfiles := url.NewFiles()\n// SetFile(name,value)\n// name为字段名，value为值\nfiles.SetField(\"name\",\"value\")\nreq := url.NewRequest()\nreq.Files = files\nr, err := requests.Post(\"http://httpbin.org/post\",req)\nif err != nil {\n    fmt.Println(err)\n}\nfmt.Println(r.Text)\n\n...\n\"form\": {\n\t\"name\": \"value\"\n}\n...\n```\n\n## POST发送text/plain文本\nrequests支持post传输普通文本信息，默认content-type=text/plain，也可以自定义content-type。\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wangluozhe/requests\"\n\t\"github.com/wangluozhe/requests/url\"\n)\n\nfunc main() {\n\treq := url.NewRequest()\n\theaders := url.NewHeaders()\n\theaders.Set(\"User-Agent\", \"123\")\n\treq.Headers = headers\n\treq.Body = \"testdata\"\n\tr, _ := requests.Post(\"https://httpbin.org/post\", req)\n\tfmt.Println(r.Text)\n}\n```\n\n\n\n## 响应状态码\n\n我们可以检测响应状态码：\n\n```go\nr, err := requests.Get(\"http://httpbin.org/get\", nil)\nfmt.Println(r.StatusCode)\n\n200\n```\n\n为方便引用，可以直接使用此方法：\n\n```go\nfmt.Println(r.StatusCode == http.StatusOK)\n\nTrue\n```\n\n如果发送了一个错误请求(一个 4XX 客户端错误，或者 5XX 服务器错误响应)，我们可以通过 `Response.RaiseForStatus()` 来抛出异常：\n\n```go\nr, err := requests.Get(\"http://httpbin.org/status/404\", nil)\nfmt.Println(r.StatusCode)\n\n404\n\nfmt.Println(r.RaiseForStatus())\n\n404 Client Error\n```\n\n但是，由于我们的例子中 `r` 的 `StatusCode` 是 `200` ，当我们调用 `RaiseForStatus()` 时，得到的是：\n\n```go\nfmt.Println(r.RaiseForStatus())\n\nnil\n```\n\n一切都挺和谐哈。\n\n\n\n## 响应头\n\n我们可以查看以一个 http.Header形式（实际是一个map[string]\\[]string类型）展示的服务器响应头：\n\n```go\nfmt.Println(r.Headers)\n\nmap[Access-Control-Allow-Credentials:[true] Access-Control-Allow-Origin:[*] Connection:[keep-alive] Content-Length:[1976] Content-Type:[application/json] Date:[Sat, 12 Mar 2022 15:59:05 GMT] Server:[gunicorn/19.9.0]]\n```\n\n但是这个类型比较特殊：它是仅为 HTTP 头部而生的。根据 [RFC 2616](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html)， HTTP 头部是大小写不敏感的。\n\n因此，我们可以使用任意大写形式来访问这些响应头字段：\n\n```go\nfmt.Println(r.Headers[\"Content-Type\"][0])\napplication/json\n\nfmt.Println(r.Headers.Get(\"content-type\"))\napplication/json\n```\n\n它还有一个特殊点，那就是服务器可以多次接受同一 header，每次都使用不同的值。但 Requests 会将它们合并，这样它们就可以用一个映射来表示出来，参见 [RFC 7230](http://tools.ietf.org/html/rfc7230#section-3.2):\n\n\u003e A recipient MAY combine multiple header fields with the same field name into one \"field-name: field-value\" pair, without changing the semantics of the message, by appending each subsequent field value to the combined field value in order, separated by a comma.\n\u003e\n\u003e 接收者可以合并多个相同名称的 header 栏位，把它们合为一个 \"field-name: field-value\" 配对，将每个后续的栏位值依次追加到合并的栏位值中，用逗号隔开即可，这样做不会改变信息的语义。\n\n\n\n## Cookie\n\n如果某个响应中包含一些 cookie，你可以快速访问它们：\n\n```go\nurl := \"https://www.baidu.com\"\nr, err := requests.Get(url, nil)\n\nfmt.Println(r.Cookies)\n\n[BD_NOT_HTTPS=1; Path=/; Max-Age=300 BIDUPSID=7DB59A8D47E763943295969C33979837; Path=/; Domain=baidu.com; Max-Age=2147483647 PSTM=1647233990; Path=/; Domain=baidu.com; Max-Age=2147483647 BAIDUID=7DB59A8D47E7639495833AF6370F9985:FG=1; Path=/; Domain=baidu.com; Max-Age=31536000]\n```\n\n要想发送你的cookies到服务器，可以使用 `cookies` 参数：\n\n```go\nreq := url.NewRequest()\ncookies,_ := cookiejar.New(nil)\n// cookies := url.NewCookies() // 推荐使用这种\nurls, _ := url.Parse(\"http://httpbin.org/cookies\")\ncookies.SetCookies(urls,[]*http.Cookie{\u0026http.Cookie{\n    Name:       \"cookies_are\",\n    Value:      \"working\",\n}})\nreq.Cookies = cookies\nr, err := requests.Get(\"http://httpbin.org/cookies\", req)\nif err != nil {\n    fmt.Println(err)\n}\n\nfmt.Println(r.Text)\n\n{\"cookies\": {\"cookies_are\": \"working\"}}\n```\n\n或者：\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wangluozhe/requests\"\n\t\"github.com/wangluozhe/requests/url\"\n)\n\nfunc main() {\n\trawUrl := \"http://httpbin.org/cookies\"\n\treq := url.NewRequest()\n\t//cookies := map[string]string{\n\t//\t\"name\":     \"zhangsan\",\n\t//\t\"age\":      \"10\",\n\t//\t\"language\": \"en\",\n\t//}\n\t//cookies := map[string]int{\n\t//\t\"age\":   20,\n\t//\t\"page\":  2,\n\t//\t\"limit\": 10,\n\t//}\n\tcookies := map[string]interface{}{\n\t\t\"Hm_lpvt_def79de877408c7bd826e49b694147bc\":     1648301329,\n\t\t\"Hm_lvt_def79de877408c7bd826e49b694147bc\":      \"1647245863,1647936048,1648296630\",\n\t\t\"_ga\": \"GA1.1.630251354.1645893020\",\n\t}\n\treq.Cookies = url.ParseCookies(rawUrl, cookies)\n\t//req.Cookies = url.ParseCookies(rawUrl,\"_ga=GA1.1.630251354.1645893020; Hm_lvt_def79de877408c7bd826e49b694147bc=1647245863,1647936048,1648296630; Hm_lpvt_def79de877408c7bd826e49b694147bc=1648301329\")\n\tr, err := requests.Get(rawUrl, req)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\tfmt.Println(r.Text)\n}\n\n\n{\n  \"cookies\": {\n    \"Hm_lpvt_def79de877408c7bd826e49b694147bc\": \"1648301329\", \n    \"Hm_lvt_def79de877408c7bd826e49b694147bc\": \"1647245863,1647936048,1648296630\", \n    \"_ga\": \"GA1.1.630251354.1645893020\"\n  }\n}\n```\n\n\n\n## 重定向与请求历史\n\n默认情况下，除了 HEAD, Requests 会自动处理所有重定向。\n\n可以使用响应对象的 `history` 方法来追踪重定向。\n\n`Response.History` 是一个 `Response` 对象的列表，为了完成请求而创建了这些对象。这个对象列表按照从最老到最近的请求进行排序。\n\n例如，Github 将所有的 HTTP 请求重定向到 HTTPS：\n\n```go\nr, err := requests.Get(\"http://github.com\", nil)\n\nfmt.Println(r.Url)\n\nhttps://github.com/\n\nfmt.Println(r.StatusCode)\n\n200\n\nfmt.Println(r.History)\n\n[0xc0001803f0]\n```\n\n如果你使用的是GET、OPTIONS、POST、PUT、PATCH 或者 DELETE，那么你可以通过 `allow_redirects` 参数禁用重定向处理：\n\n`注：跳转链接请到headers中自行获取`\n\n```go\nreq := url.NewRequest()\nreq.AllowRedirects = false\nr, err := requests.Get(\"http://github.com\", req)\nif err != nil {\n    fmt.Println(err)\n}\nfmt.Println(r.StatusCode)\n\n301\n\nfmt.Println(r.History)\n\n[]\n```\n\n如果你使用了 HEAD，你也可以启用重定向：\n\n```go\nreq := url.NewRequest()\nreq.AllowRedirects = true\nr, err := requests.Get(\"http://github.com\", req)\nif err != nil {\n\tfmt.Println(err)\n}\nfmt.Println(r.Url)\n\nhttps://github.com/\n\nfmt.Println(r.History)\n\n[0xc0001803f0]\n```\n\n\n\n## 超时\n\n你可以告诉 requests 在经过以 `Timeout` 参数设定的秒数时间之后停止等待响应。基本上所有的生产代码都应该使用这一参数。如果不使用，你的程序可能会永远失去响应：\n\n```go\nreq := url.NewRequest()\nreq.Timeout = 1 * time.Millisecond\nr, err := requests.Get(\"http://github.com\",req)\nif err != nil {\n    fmt.Println(err)\n}\n\npanic: runtime error: invalid memory address or nil pointer dereference\n[signal 0xc0000005 code=0x0 addr=0x0 pc=0x253460]\n\ngoroutine 1 [running]:\nmain.main()\n\tD:/Go/github.com/wangluozhe/requests/examples/test.go:27 +0xc0\n```\n\n注意\n\n`Timeout` 仅对连接过程有效，与响应体的下载无关。 `Timeout` 并不是整个下载响应的时间限制，而是如果服务器在 `Timeout` 秒内没有应答，将会引发一个异常（更精确地说，是在 `Timeout` 秒内没有从基础套接字上接收到任何字节的数据时）If no timeout is specified explicitly, requests do not time out.\n\n\n\n## 基本身份认证\n\n许多要求身份认证的web服务都接受 HTTP Basic Auth。这是最简单的一种身份认证，并且 requests 对这种认证方式的支持是直接开箱即可用。\n\n以 HTTP Basic Auth 发送请求非常简单：\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wangluozhe/requests\"\n\t\"github.com/wangluozhe/requests/url\"\n)\n\nfunc main() {\n\treq := url.NewRequest()\n\treq.Auth = []string{\"user\",\"password\"}\n\tr, err := requests.Get(\"http://httpbin.org/basic-auth/user/password\",req)\n\tif err != nil{\n\t\tfmt.Println(err)\n\t}\n\tfmt.Println(\"text:\",r.Text)\n}\n\n{\n  \"authenticated\": true, \n  \"user\": \"user\"\n}\n```\n\n\n\n## 客户端证书\n\n你也可以指定一个本地证书用作客户端证书，可以是一个包含两个文件路径的数组（cert，key）或一个包含三个文件路径的数组（cert，key，根证书）：\n\n```go\nreq := url.NewRequest()\nreq.Cert = []string{\"cert\",\"key\"}\n// req.Cert = []string{\"cert\",\"key\",\"rootca\"}\nr, err := requests.Get(\"xxx\",req)\nif err != nil{\n    fmt.Println(err)\n}\n```\n\n或者保持在会话中：\n\n```go\nsession := requests.NewSession()\nsession.Cert = []string{\"cert\",\"key\"}\n```\n\n\n\n## JA3指纹\n\nrequests也支持JA3指纹的修改，可以让你在访问的时候使用你自己定义的JA3指纹进行TLS握手访问，但是请注意，JA3指纹必须符合要求，不能随便更改，最好使用wireshark或者ja3er.com获取标准指纹，而不是随便输入一串数字。\n\n```go\nreq := url.NewRequest()\nheaders := url.NewHeaders()\nheaders.Set(\"User-Agent\", \"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36\")\nreq.Headers = headers\nreq.Ja3 = \"771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-21,29-23-24,0\"\nr, err := requests.Get(\"https://ja3er.com/json\", req)\nif err != nil {\n\tfmt.Println(err)\n}\nfmt.Println(r.Text)\n\n{\"ja3_hash\":\"b32309a26951912be7dba376398abc3b\", \"transport\": \"771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-21,29-23-24,0\", \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36\"}\n```\n\n## TLS指纹\n\nrequests支持你随意修改TLS指纹信息\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\thttp \"github.com/wangluozhe/chttp\"\n\t\"github.com/wangluozhe/requests\"\n\t\"github.com/wangluozhe/requests/transport\"\n\t\"github.com/wangluozhe/requests/url\"\n)\n\nfunc main() {\n\treq := url.NewRequest()\n\theaders := \u0026http.Header{\n\t\t\"User-Agent\":                []string{\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/112.0\"},\n\t\t\"accept\":                    []string{\"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\"},\n\t\t\"accept-language\":           []string{\"zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2\"},\n\t\t\"accept-encoding\":           []string{\"gzip, deflate, br\"},\n\t\t\"upgrade-insecure-requests\": []string{\"1\"},\n\t\t\"sec-fetch-dest\":            []string{\"document\"},\n\t\t\"sec-fetch-mode\":            []string{\"navigate\"},\n\t\t\"sec-fetch-site\":            []string{\"none\"},\n\t\t\"sec-fetch-user\":            []string{\"?1\"},\n\t\t\"te\":                        []string{\"trailers\"},\n\t\thttp.PHeaderOrderKey: []string{\n\t\t\t\":method\",\n\t\t\t\":path\",\n\t\t\t\":authority\",\n\t\t\t\":scheme\",\n\t\t},\n\t\thttp.HeaderOrderKey: []string{\n\t\t\t\"user-agent\",\n\t\t\t\"accept\",\n\t\t\t\"accept-language\",\n\t\t\t\"accept-encoding\",\n\t\t\t\"upgrade-insecure-requests\",\n\t\t\t\"sec-fetch-dest\",\n\t\t\t\"sec-fetch-mode\",\n\t\t\t\"sec-fetch-site\",\n\t\t\t\"sec-fetch-user\",\n\t\t\t\"te\",\n\t\t},\n\t}\n\treq.Headers = headers\n\treq.Ja3 = \"771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-21,29-23-24,0\"\n\tes := \u0026transport.Extensions{\n\t\tSupportedSignatureAlgorithms: []string{\n\t\t\t\"ECDSAWithP256AndSHA256\",\n\t\t\t\"ECDSAWithP384AndSHA384\",\n\t\t\t\"ECDSAWithP521AndSHA512\",\n\t\t\t\"PSSWithSHA256\",\n\t\t\t\"PSSWithSHA384\",\n\t\t\t\"PSSWithSHA512\",\n\t\t\t\"PKCS1WithSHA256\",\n\t\t\t\"PKCS1WithSHA384\",\n\t\t\t\"PKCS1WithSHA512\",\n\t\t\t\"ECDSAWithSHA1\",\n\t\t\t\"PKCS1WithSHA1\",\n\t\t},\n\t\t//CertCompressionAlgo: []string{\n\t\t//\t\"brotli\",\n\t\t//},\n\t\tRecordSizeLimit: 4001,\n\t\tDelegatedCredentials: []string{\n\t\t\t\"ECDSAWithP256AndSHA256\",\n\t\t\t\"ECDSAWithP384AndSHA384\",\n\t\t\t\"ECDSAWithP521AndSHA512\",\n\t\t\t\"ECDSAWithSHA1\",\n\t\t},\n\t\tSupportedVersions: []string{\n\t\t\t\"1.3\",\n\t\t\t\"1.2\",\n\t\t},\n\t\tPSKKeyExchangeModes: []string{\n\t\t\t\"PskModeDHE\",\n\t\t},\n\t\tKeyShareCurves: []string{\n\t\t\t\"X25519\",\n\t\t\t\"P256\",\n\t\t},\n\t}\n\ttes := transport.ToTLSExtensions(es)\n\treq.TLSExtensions = tes\n\tr, err := requests.Get(\"https://tls.peet.ws/api/all\", req)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\tfmt.Println(r.Request.Headers)\n\tfmt.Println(\"url:\", r.Url)\n\tfmt.Println(\"headers:\", r.Headers)\n\tfmt.Println(\"text:\", r.Text)\n}\n\n```\n\n## HTTP2指纹\n\nrequests支持HTTP2指纹信息的修改\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\thttp \"github.com/wangluozhe/chttp\"\n\t\"github.com/wangluozhe/requests\"\n\t\"github.com/wangluozhe/requests/transport\"\n\t\"github.com/wangluozhe/requests/url\"\n)\n\nfunc main() {\n\treq := url.NewRequest()\n\theaders := \u0026http.Header{\n\t\t\"User-Agent\":                []string{\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/112.0\"},\n\t\t\"accept\":                    []string{\"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8\"},\n\t\t\"accept-language\":           []string{\"zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2\"},\n\t\t\"accept-encoding\":           []string{\"gzip, deflate, br\"},\n\t\t\"upgrade-insecure-requests\": []string{\"1\"},\n\t\t\"sec-fetch-dest\":            []string{\"document\"},\n\t\t\"sec-fetch-mode\":            []string{\"navigate\"},\n\t\t\"sec-fetch-site\":            []string{\"none\"},\n\t\t\"sec-fetch-user\":            []string{\"?1\"},\n\t\t\"te\":                        []string{\"trailers\"},\n\t\thttp.PHeaderOrderKey: []string{\n\t\t\t\":method\",\n\t\t\t\":path\",\n\t\t\t\":authority\",\n\t\t\t\":scheme\",\n\t\t},\n\t\thttp.HeaderOrderKey: []string{\n\t\t\t\"user-agent\",\n\t\t\t\"accept\",\n\t\t\t\"accept-language\",\n\t\t\t\"accept-encoding\",\n\t\t\t\"upgrade-insecure-requests\",\n\t\t\t\"sec-fetch-dest\",\n\t\t\t\"sec-fetch-mode\",\n\t\t\t\"sec-fetch-site\",\n\t\t\t\"sec-fetch-user\",\n\t\t\t\"te\",\n\t\t},\n\t}\n\treq.Headers = headers\n\treq.Ja3 = \"771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-21,29-23-24,0\"\n\th2s := \u0026transport.H2Settings{\n\t\tSettings: map[string]int{\n\t\t\t\"HEADER_TABLE_SIZE\": 65536,\n\t\t\t//\"ENABLE_PUSH\":            0,\n\t\t\t//\"MAX_HEADER_LIST_SIZE\":   262144,\n\t\t\t//\"MAX_CONCURRENT_STREAMS\": 1000,\n\t\t\t\"INITIAL_WINDOW_SIZE\": 131072,\n\t\t\t\"MAX_FRAME_SIZE\":      16384,\n\t\t},\n\t\tSettingsOrder: []string{\n\t\t\t\"HEADER_TABLE_SIZE\",\n\t\t\t\"INITIAL_WINDOW_SIZE\",\n\t\t\t\"MAX_FRAME_SIZE\",\n\t\t},\n\t\tConnectionFlow: 12517377,\n\t\tHeaderPriority: map[string]interface{}{\n\t\t\t\"weight\":    42,\n\t\t\t\"streamDep\": 13,\n\t\t\t\"exclusive\": false,\n\t\t},\n\t\tPriorityFrames: []map[string]interface{}{\n\t\t\t{\n\t\t\t\t\"streamID\": 3,\n\t\t\t\t\"priorityParam\": map[string]interface{}{\n\t\t\t\t\t\"weight\":    201,\n\t\t\t\t\t\"streamDep\": 0,\n\t\t\t\t\t\"exclusive\": false,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"streamID\": 5,\n\t\t\t\t\"priorityParam\": map[string]interface{}{\n\t\t\t\t\t\"weight\":    101,\n\t\t\t\t\t\"streamDep\": 0,\n\t\t\t\t\t\"exclusive\": false,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"streamID\": 7,\n\t\t\t\t\"priorityParam\": map[string]interface{}{\n\t\t\t\t\t\"weight\":    1,\n\t\t\t\t\t\"streamDep\": 0,\n\t\t\t\t\t\"exclusive\": false,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"streamID\": 9,\n\t\t\t\t\"priorityParam\": map[string]interface{}{\n\t\t\t\t\t\"weight\":    1,\n\t\t\t\t\t\"streamDep\": 7,\n\t\t\t\t\t\"exclusive\": false,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"streamID\": 11,\n\t\t\t\t\"priorityParam\": map[string]interface{}{\n\t\t\t\t\t\"weight\":    1,\n\t\t\t\t\t\"streamDep\": 3,\n\t\t\t\t\t\"exclusive\": false,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"streamID\": 13,\n\t\t\t\t\"priorityParam\": map[string]interface{}{\n\t\t\t\t\t\"weight\":    241,\n\t\t\t\t\t\"streamDep\": 0,\n\t\t\t\t\t\"exclusive\": false,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\th2ss := transport.ToHTTP2Settings(h2s)\n\treq.HTTP2Settings = h2ss\n\tr, err := requests.Get(\"https://tls.peet.ws/api/all\", req)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\tfmt.Println(r.Request.Headers)\n\tfmt.Println(\"url:\", r.Url)\n\tfmt.Println(\"headers:\", r.Headers)\n\tfmt.Println(\"text:\", r.Text)\n}\n\n```\n\n\n## JA4指纹\n\n`JA4`是什么，怎么组成的，请看华总的文章[JA4概要](https://blog.csdn.net/Y_morph/article/details/133747866?spm=1001.2014.3001.5501)\n\n```golang\npackage main\n\nimport (\n\t\"fmt\"\n\thttp \"github.com/wangluozhe/chttp\"\n\t\"github.com/wangluozhe/requests\"\n\t\"github.com/wangluozhe/requests/transport\"\n\t\"github.com/wangluozhe/requests/url\"\n)\n\nfunc main() {\n\treq := url.NewRequest()\n\theaders := \u0026http.Header{\n\t\t\"Accept\":                    []string{\"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\"},\n\t\t\"Accept-Encoding\":           []string{\"gzip, deflate, br\"},\n\t\t\"Accept-Language\":           []string{\"zh-CN,zh;q=0.9\"},\n\t\t\"Cache-Control\":             []string{\"no-cache\"},\n\t\t\"Connection\":                []string{\"keep-alive\"},\n\t\t\"Host\":                      []string{\"gospider2.gospiderb.asia:8998\"},\n\t\t\"Pragma\":                    []string{\"no-cache\"},\n\t\t\"sec-ch-ua\":                 []string{\"\\\".Not/A)Brand\\\";v=\\\"99\\\", \\\"Google Chrome\\\";v=\\\"103\\\", \\\"Chromium\\\";v=\\\"103\\\"\"},\n\t\t\"sec-ch-ua-mobile\":          []string{\"\\\"?0\\\"\"},\n\t\t\"sec-ch-ua-platform\":        []string{\"\\\"Windows\\\"\"},\n\t\t\"Sec-Fetch-Dest\":            []string{\"document\"},\n\t\t\"Sec-Fetch-Mode\":            []string{\"navigate\"},\n\t\t\"Sec-Fetch-Site\":            []string{\"none\"},\n\t\t\"Sec-Fetch-User\":            []string{\"\\\"?1\\\"\"},\n\t\t\"Upgrade-Insecure-Requests\": []string{\"1\"},\n\t\t\"User-Agent\":                []string{\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36\"},\n\t\thttp.HeaderOrderKey: []string{\n\t\t\t\"HOST\",\n\t\t\t\"connection\",\n\t\t\t\"pragma\",\n\t\t\t\"Cache-Control\",\n\t\t\t\"sec-ch-ua\",\n\t\t\t\"sec-ch-ua-mobile\",\n\t\t\t\"sec-ch-ua-platform\",\n\t\t\t\"upgrade-insecure-requests\",\n\t\t\t\"user-agent\",\n\t\t\t\"accept\",\n\t\t\t\"sec-fetch-site\",\n\t\t\t\"sec-fetch-mode\",\n\t\t\t\"sec-fetch-user\",\n\t\t\t\"sec-fetch-dest\",\n\t\t\t\"accept-encoding\",\n\t\t\t\"accept-language\",\n\t\t},\n\t\thttp.UnChangedHeaderKey: []string{\n\t\t\t\"sec-ch-ua\",\n\t\t\t\"sec-ch-ua-mobile\",\n\t\t\t\"sec-ch-ua-platform\",\n\t\t},\n\t}\n\treq.Headers = headers\n\treq.Ja3 = \"772,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-21-41,29-23-24,0\"\n\treq.ForceHTTP1 = true\n\tes := \u0026transport.Extensions{\n\t\tSupportedSignatureAlgorithms: []string{\n\t\t\t\"ecdsa_secp256r1_sha256\",\n\t\t\t\"rsa_pss_rsae_sha256\",\n\t\t\t\"rsa_pkcs1_sha256\",\n\t\t\t\"ecdsa_secp384r1_sha384\",\n\t\t\t\"rsa_pss_rsae_sha384\",\n\t\t\t\"rsa_pkcs1_sha384\",\n\t\t\t\"rsa_pss_rsae_sha512\",\n\t\t\t\"rsa_pkcs1_sha512\",\n\t\t},\n\t\tCertCompressionAlgo: []string{\n\t\t\t\"brotli\",\n\t\t},\n\t\tRecordSizeLimit: 4001,\n\t\tDelegatedCredentials: []string{\n\t\t\t\"ECDSAWithP256AndSHA256\",\n\t\t\t\"ECDSAWithP384AndSHA384\",\n\t\t\t\"ECDSAWithP521AndSHA512\",\n\t\t\t\"ECDSAWithSHA1\",\n\t\t},\n\t\tSupportedVersions: []string{\n\t\t\t\"GREASE\",\n\t\t\t\"1.3\",\n\t\t\t\"1.2\",\n\t\t},\n\t\tPSKKeyExchangeModes: []string{\n\t\t\t\"PskModeDHE\",\n\t\t},\n\t\tKeyShareCurves: []string{\n\t\t\t\"GREASE\",\n\t\t\t\"X25519\",\n\t\t},\n\t}\n\ttes := transport.ToTLSExtensions(es)\n\treq.TLSExtensions = tes\n\tr, err := requests.Get(\"https://gospider2.gospiderb.asia:8998/\", req)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\tfmt.Println(r.Request.Headers)\n\tfmt.Println(\"url:\", r.Url)\n\tfmt.Println(\"headers:\", r.Headers)\n\tfmt.Println(\"text:\", r.Text)\n}\n\n// 模拟后的结果\n// JA4:  t13d1516h1_dea800f94266_27c5da80acb3\n// JA4H: ge11nn13zhcn_d8f538a17def_e3b0c44298fc_e3b0c44298fc\n```\n\n\n# 编码\n\nrequests支持一些常用的编码方式，并且命名更使人易懂。传递的参数可为`字符串（string）`或`字符数组（[]byte）`类型。\n\n\n\n## 16进制编码\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wangluozhe/requests/utils\"\n)\n\nfunc main() {\n\turl := \"https://www.baidu.com\"\n\thexen := utils.HexEncode(url)\n\tfmt.Println(hexen)\n\tfmt.Println(string(hexen))\n\thexde := utils.HexDecode(hexen)\n\tfmt.Println(hexde)\n\tfmt.Println(string(hexde))\n}\n\n[54 56 55 52 55 52 55 48 55 51 51 97 50 102 50 102 55 55 55 55 55 55 50 101 54 50 54 49 54 57 54 52 55 53 50 101 54 51 54 102 54 100]\n68747470733a2f2f7777772e62616964752e636f6d\n[104 116 116 112 115 58 47 47 119 119 119 46 98 97 105 100 117 46 99 111 109]\nhttps://www.baidu.com\n```\n\n\n\n## URI编码\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wangluozhe/requests/utils\"\n)\n\nfunc main() {\n\turl := \"https://www.baidu.com?page=10\u0026abc=123\u0026name=你好啊\"\n\tencode := utils.EncodeURIComponent(url)\n\tfmt.Println(encode)\n\tdecode := utils.DecodeURIComponent(encode)\n\tfmt.Println(decode)\n    encode1 := utils.EncodeURI(url)\n\tfmt.Println(encode1)\n\tdecode1 := utils.DecodeURI(encode1)\n\tfmt.Println(decode1)\n    escape := utils.Escape(url)\n\tfmt.Println(escape)\n\tunescape := utils.UnEscape(escape)\n\tfmt.Println(unescape)\n}\n\nhttps%3A%2F%2Fwww.baidu.com%3Fpage%3D10%26abc%3D123%26name%3D%E4%BD%A0%E5%A5%BD%E5%95%8A\nhttps://www.baidu.com?page=10\u0026abc=123\u0026name=你好啊\nhttps://www.baidu.com?page=10\u0026abc=123\u0026name=%E4%BD%A0%E5%A5%BD%E5%95%8A\nhttps://www.baidu.com?page=10\u0026abc=123\u0026name=你好啊\nhttps%3A//www.baidu.com%3Fpage%3D10%26abc%3D123%26name%3D%u4f60%u597d%u554a\nhttps://www.baidu.com?page=10\u0026abc=123\u0026name=你好啊\n```\n\n\n\n## Base64编码\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wangluozhe/requests/utils\"\n)\n\nfunc main() {\n\turl := \"https://www.baidu.com?page=10\u0026abc=123\u0026name=你好啊\"\n    base32en := utils.Base32Encode(url)\n\tfmt.Println(base32en)\n\tbase32de := utils.Base32Decode(base32en)\n\tfmt.Println(base32de)\n\tbase64en := utils.Base64Encode(url)\n\tfmt.Println(base64en)\n\tbase64de := utils.Base64Decode(base64en)\n\tfmt.Println(base64de)\n    // 或者像JavaScript语言一样\n\tbtoa := utils.Btoa(url)\n\tfmt.Println(btoa)\n\tatob := utils.Atob(btoa)\n\tfmt.Println(atob)\n}\n\nNB2HI4DTHIXS653XO4XGEYLJMR2S4Y3PNU7XAYLHMU6TCMBGMFRGGPJRGIZSM3TBNVST3ZF5UDS2LPPFSWFA====\nhttps://www.baidu.com?page=10\u0026abc=123\u0026name=你好啊\naHR0cHM6Ly93d3cuYmFpZHUuY29tP3BhZ2U9MTAmYWJjPTEyMyZuYW1lPeS9oOWlveWVig==\nhttps://www.baidu.com?page=10\u0026abc=123\u0026name=你好啊\naHR0cHM6Ly93d3cuYmFpZHUuY29tP3BhZ2U9MTAmYWJjPTEyMyZuYW1lPeS9oOWlveWVig==\nhttps://www.baidu.com?page=10\u0026abc=123\u0026name=你好啊\n```\n\n\n\n# 加密算法\n\nrequests支持一些常用的加密算法，并且命名更使人易懂。传递的参数可为`字符串（string）`或`字符数组（[]byte）`类型。\n\n\n\n## 线性散列（Hash）算法\n\n`MD系列`：\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wangluozhe/requests/utils\"\n)\n\nfunc main() {\n\tm := utils.MD4(\"123\")\n\tfmt.Println(\"MD4:\", m)\n\n\tm = utils.RIPEMD160(\"123\")\n\tfmt.Println(\"RIPEMD160:\", m)\n\n\tm = utils.MD5(\"123\")\n\tfmt.Println(\"MD5:\", m)\n}\n\nMD4: c58cda49f00748a3bc0fcfa511d516cb\nRIPEMD160: e3431a8e0adbf96fd140103dc6f63a3f8fa343ab\nMD5: 202cb962ac59075b964b07152d234b70\n```\n\n`SHA系列`：\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wangluozhe/requests/utils\"\n)\n\nfunc main() {\n\ts1 := utils.SHA1(\"123\")\n\tb64 := utils.Btoa(s1)\n\th16 := utils.HexEncode(s1)\n\tfmt.Println(\"SHA1-base64:\", b64)\n\tfmt.Println(\"SHA1-hex:\", string(h16))\n\n\ts2 := utils.SHA224(\"123\")\n\tb64 = utils.Btoa(s2)\n\th16 = utils.HexEncode(s2)\n\tfmt.Println(\"SHA224-base64:\", b64)\n\tfmt.Println(\"SHA224-hex:\", string(h16))\n\n\ts2 = utils.SHA256(\"123\")\n\tb64 = utils.Btoa(s2)\n\th16 = utils.HexEncode(s2)\n\tfmt.Println(\"SHA256-base64:\", b64)\n\tfmt.Println(\"SHA256-hex:\", string(h16))\n\n\ts5 := utils.SHA384(\"123\")\n\tb64 = utils.Btoa(s5)\n\th16 = utils.HexEncode(s5)\n\tfmt.Println(\"SHA384-base64:\", b64)\n\tfmt.Println(\"SHA384-hex:\", string(h16))\n\n\ts5 = utils.SHA512(\"123\")\n\tb64 = utils.Btoa(s5)\n\th16 = utils.HexEncode(s5)\n\tfmt.Println(\"SHA512-base64:\", b64)\n\tfmt.Println(\"SHA512-hex:\", string(h16))\n}\n\nSHA1-base64: QL0AFWMIX8NRZTKeof9cXsvbvu8=\nSHA1-hex: 40bd001563085fc35165329ea1ff5c5ecbdbbeef\nSHA224-base64: eNgEXWhKvS7s6SN1jzzXgUid86SOEniYJGYBfw==\nSHA224-hex: 78d8045d684abd2eece923758f3cd781489df3a48e1278982466017f\nSHA256-base64: pmWkWSBCL51Bfkhn79xPuKBKHz//H6B+mY6G9/eieuM=\nSHA256-hex: a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3\nSHA384-base64: mgqC8MDPMUcNev/t40BsyaqEEGcVILcnBE7aFbTCVTKptc2Kr5zsSRnXYlW2v7AP\nSHA384-hex: 9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f\nSHA512-base64: PJkJr+wlNU1VHa4hWQuybjjVPyFzuNPcPu5MBH56scHri4UQPjvnumE7MbtcnDYhTcnxSkL9ei/bhIVrylxEwg==\nSHA512-hex: 3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2\n```\n\n`Hmac系列`：\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wangluozhe/requests/utils\"\n)\n\nfunc main() {\n\tmd4 := utils.HmacMD4(\"123\", \"123\")\n\tbs64 := utils.Btoa(md4)\n\thex := utils.HexEncode(md4)\n\tfmt.Println(\"HmacMD4-base64:\", bs64)\n\tfmt.Println(\"HmacMD4-hex:\", string(hex))\n\n\tr160 := utils.HmacRIPEMD160(\"123\", \"123\")\n\tbs64 = utils.Btoa(r160)\n\thex = utils.HexEncode(r160)\n\tfmt.Println(\"HmacRIPEMD160-base64:\", bs64)\n\tfmt.Println(\"HmacRIPEMD160-hex:\", string(hex))\n\n\tmd5 := utils.HmacMD5(\"123\", \"123\")\n\tbs64 = utils.Btoa(md5)\n\thex = utils.HexEncode(md5)\n\tfmt.Println(\"HmacMD5-base64:\", bs64)\n\tfmt.Println(\"HmacMD5-hex:\", string(hex))\n\n\tsha1 := utils.HmacSHA1(\"123\", \"123\")\n\tbs64 = utils.Btoa(sha1)\n\thex1 := utils.HexEncode(sha1)\n\tfmt.Println(\"HmacSHA1-base64:\", bs64)\n\tfmt.Println(\"HmacSHA1-hex:\", string(hex1))\n\n\tsha224 := utils.HmacSHA224(\"123\", \"123\")\n\tbs64 = utils.Btoa(sha224)\n\thex2 := utils.HexEncode(sha224)\n\tfmt.Println(\"HmacSHA224-base64:\", bs64)\n\tfmt.Println(\"HmacSHA224-hex:\", string(hex2))\n\n\tsha256 := utils.HmacSHA256(\"123\", \"123\")\n\tbs64 = utils.Btoa(sha256)\n\thex3 := utils.HexEncode(sha256)\n\tfmt.Println(\"HmacSHA256-base64:\", bs64)\n\tfmt.Println(\"HmacSHA256-hex:\", string(hex3))\n\n\tsha384 := utils.HmacSHA384(\"123\", \"123\")\n\tbs64 = utils.Btoa(sha384)\n\thex4 := utils.HexEncode(sha384)\n\tfmt.Println(\"HmacSHA384-base64:\", bs64)\n\tfmt.Println(\"HmacSHA384-hex:\", string(hex4))\n\n\tsha512 := utils.HmacSHA512(\"123\", \"123\")\n\tbs64 = utils.Btoa(sha512)\n\thex5 := utils.HexEncode(sha512)\n\tfmt.Println(\"HmacSHA512-base64:\", bs64)\n\tfmt.Println(\"HmacSHA512-hex:\", string(hex5))\n}\n\nHmacMD4-base64: u3owGP+65If/IdHlG8klJg==\nHmacMD4-hex: bb7a3018ffbae487ff21d1e51bc92526\nHmacRIPEMD160-base64: Wt1vTR04ulq64/WbCZsoGMY1wM8=\nHmacRIPEMD160-hex: 5add6f4d1d38ba5abae3f59b099b2818c635c0cf\nHmacMD5-base64: sqHsDz4GBwmdfzl5HATppA==\nHmacMD5-hex: b2a1ec0f3e0607099d7f39791c04e9a4\nHmacSHA1-base64: o8Ak8BzMs7Y0V9hIsNL4nB90Sj0=\nHmacSHA1-hex: a3c024f01cccb3b63457d848b0d2f89c1f744a3d\nHmacSHA224-base64: +S2OBxrerlFMGsD5RQLnW7XCi4F+DgoB52I0jw==\nHmacSHA224-hex: f92d8e071adeae514c1ac0f94502e75bb5c28b817e0e0a01e762348f\nHmacSHA256-base64: PK/kD5K+asd9J5K0smfC2hHj8wh7k7sZxsUTN4aYS0Q=\nHmacSHA256-hex: 3cafe40f92be6ac77d2792b4b267c2da11e3f3087b93bb19c6c5133786984b44\nHmacSHA384-base64: b2i1J57kVppw+dC071Gk25fXfLkBmcILY38gkOOXgPjuyE8wK+LuP+w2pzTZ5tpb\nHmacSHA384-hex: 6f68b5279ee4569a70f9d0b4ef51a4db97d77cb90199c20b637f2090e39780f8eec84f302be2ee3fec36a734d9e6da5b\nHmacSHA512-base64: BjT9BDgLuvUGnIxGp0x9Id90FIiNmAwnoW1eJiy4yQWROcIS0JJgAPrwJuSDkEzvri9enZvV9R+8KsTE3lGBFQ==\nHmacSHA512-hex: 0634fd04380bbaf5069c8c46a74c7d21df7414888d980c27a16d5e262cb8c9059139c212d0926000faf026e483904cefae2f5e9d9bd5f51fbc2ac4c4de518115\n```\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwangluozhe%2Frequests","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwangluozhe%2Frequests","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwangluozhe%2Frequests/lists"}