之前做 golang 开发的时候,用的是 beego 框架,框架的好处是,把所有工具都封装好了,在获取参数的时候,只要调用相应的方法,就能取得对应的数据。
而最近在从零开始,原生写一个小说爬虫管理的web服务功能时,发现自己所掌握的那点知识,并不能满足自己的开发需求,测试好多遍都未果,希望写下这篇记录贴,供以后回顾。
数据提交场景大致如下:
1、表单提交,纯粹的 Form 表单提交数据;
2、表单上传文件,利用 Form 表单上传文件;
3、ajax 提交 json 数据;
4、ajax 提交 表单数据;
5、ajax 上传文件;
下面我将对以上五种场景进行实际的示例展示,并采用 Fetch API 代替 ajax 发送请求。
示例1:html表单提交数据
<form action="http://127.0.0.1:8088/api/task?debug=1" method="POST">
<input type="text" name="username" placeholder="username">
<input type="text" name="password" placeholder="password">
<input type="submit" value="Submit">
form>
r.ParseForm() // 首先解析表单
fmt.Println("r.Form : ", r.Form)
fmt.Println("r.Form[\"username\"]", r.Form["username"]) // 数组索引方式获取数据
fmt.Println("r.Form.get(\"password\")", r.Form.Get("password")) // Get 方式获取数据
r.Form : map[debug:[1] password:[testpass] username:[test]]
r.Form["username"] [test]
r.Form.get("password") testpass
示例2:html表单上传文件
fmt.Println("r.Form : ", r.Form)
file, fileHandler, _ := r.FormFile("file")
fmt.Println("File Header : ", fileHandler.Header)
fmt.Println("Filename : ", fileHandler.Filename)
b, _ :=ioutil.ReadAll(file) // 读取文件内容
fmt.Println(string(b))
r.Form : map[debug:[1]]
File Header : map[Content-Disposition:[form-data; name="file"; filename="url.csv"] Content-Type:[application/octet-stream]]
Filename : url.csv
http://www.aaaa.com/test/index.html
http://www.ccccc.com/test/index.php
http://www.aaaa.com/test/login.php
http://www.aaaa.com
示例3:ajax 提交json数据, golang 接收数据时,需要从request的body中,将数据读出来
<button onclick="test()">testbutton>
<script>
function test() {
fetch("http://127.0.0.1:8088/api/task?debug=1", {
body: JSON.stringify({"username":"test", "password":"test_password"}),
method: "POST",
headers: {
"Accept": "application/json",
}
}
).then(response => response.json())
.then(data => {
console.log(data);
});
}
script>
json,_ := ioutil.ReadAll(r.Body)
fmt.Println("Got params: ", string(json))
fmt.Println("Echo request: ", r)
fmt.Println("Echo request header: ", r.Header)
fmt.Println("Echo request body: ", r.Body)
fmt.Println("Echo remote addr: ", r.RemoteAddr)
fmt.Println("Echo host: ", r.Host)
fmt.Println("Echo request method: ", r.Method)
fmt.Println("Echo request UA: ", r.UserAgent())
Got params: {"username":"test","password":"test_password"}
Echo request: &{POST /api/task?debug=1 HTTP/1.1 1 1 map[Accept:[application/json] Accept-Encoding:[gzip, deflate, br] Accept-Language:[en-US,en;q=0.9] Connection:[keep-alive] Content-Length:[46] Content-Type:[text/plain;charset=UTF-8] Origin:[http://localhost:8099] Referer:[http://localhost:8099/test2.html] Sec-Fetch-Mode:[cors] Sec-Fetch-Site:[cross-site] User-Agent:[Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3879.0 Safari/537.36 Edg/78.0.249.1]] 0xc0001d6140 46 [] false 127.0.0.1:8088 map[debug:[1]] map[] map[] 127.0.0.1:61679 /api/task?debug=1 0xc0001ec210}
Echo request header: map[Accept:[application/json] Accept-Encoding:[gzip, deflate, br] Accept-Language:[en-US,en;q=0.9] Connection:[keep-alive] Content-Length:[46] Content-Type:[text/plain;charset=UTF-8] Origin:[http://localhost:8099] Referer:[http://localhost:8099/test2.html] Sec-Fetch-Mode:[cors] Sec-Fetch-Site:[cross-site] User-Agent:[Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3879.0 Safari/537.36 Edg/78.0.249.1]]
Echo request body: &{0xc0001f4020 false true {0 0} true false false 0x706ce0}
Echo remote addr: 127.0.0.1:61679
Echo host: 127.0.0.1:8088
Echo request method: POST
Echo request UA: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3879.0 Safari/537.36 Edg/78.0.249.1
示例4:ajax 提交表单数据
<button onclick="test()">testbutton>
<script>
function test() {
let formData = new FormData();
formData.set("username", "test");
formData.set("password", "test_password");
fetch("http://localhost:8088/api/task?debug=1", {
body: formData,
method: "POST",
headers: {
"Accept": "application/json"
}
}
).then(response => response.json())
.then(data => {
console.log(data);
});
}
script>
r.ParseMultipartForm(32 << 20)
fmt.Println(r.Form)
fmt.Println("username: ", r.Form.Get("username"))
fmt.Println("password: ", r.Form.Get("password"))
map[debug:[1] password:[test_password] username:[test]]
username: test
password: test_password
示例5:ajax 上传文件
<input type="file" name="test_file" id="test_file">
<button onclick="test()">testbutton>
<script>
function test() {
let formData = new FormData();
formData.set("test_file", document.getElementById("test_file").files[0]);
formData.set("password", "test_password");
fetch("http://localhost:8088/api/task?debug=1", {
body: formData,
method: "POST",
headers: {
"Accept": "application/json"
}
}
).then(response => response.json())
.then(data => {
console.log(data);
});
}
script>
r.ParseForm()
file, fileHandle, _ := r.FormFile("test_file")
fmt.Println(fileHandle.Header, fileHandle.Filename, fileHandle.Size)
b, _ := ioutil.ReadAll(file)
fmt.Println(string(b))
fmt.Println("password: ", r.Form.Get("password"))
map[Content-Disposition:[form-data; name="test_file"; filename="url.csv"] Content-Type:[application/octet-stream]] url.csv 136
http://www.aaaa.com/test/index.html
http://www.ccccc.com/test/index.php
http://www.aaaa.com/test/login.php
http://www.aaaa.com
password: test_password