前言
加更 ...?
测试用例
ajax 发送请求?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>01Jquery</title>
</head>
<body>
<span id="resp">
</span>
<script src="../js/jquery.min.js" type="text/javascript"></script>
<script>
// When data is an object, jQuery generates the data string from the object's key/value pairs unless the processData option is set to false. For example, { a: "bc", d: "e,f" } is converted to the string "a=bc&d=e%2Cf"
$.ajax({
url: "/HelloWorld/listForm",
type: "POST",
contentType : "application/x-www-form-urlencoded",
headers : {
"header01" : "thisIsHeader01",
"header02" : "thisIsHeader02"
},
data : {
param01 : "thisIsParam01",
param02 : "thisIsParam02"
},
success: function (result) {
$("#resp").text(JSON.stringify(result))
}
});
// $.ajax({
// url: "/HelloWorld/listJson",
// type: "POST",
// contentType: "application/json",
// headers: {
// "header01": "thisIsHeader01",
// "header02": "thisIsHeader02"
// },
// data: JSON.stringify({
// param01: "thisIsParam01",
// param02: "thisIsParam02"
// }),
// success: function (result) {
// $("#resp").text(JSON.stringify(result))
// }
// });
</script>
</body>
</html>
axios 发送请求?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>02Axios</title>
</head>
<body>
<span id="resp">
</span>
<script src="../js/axios.min.js" type="text/javascript"></script>
<script>
// interceptors
axios.interceptors.request.use(function (config) {
// 拦截 request, 处理请求
console.log("do sth before send request, config : ", config)
return config;
}, function (error) {
return Promise.reject(error);
});
axios.interceptors.response.use(function (response) {
// 拦截 response, 处理响应
console.log("do sth before receive response, response : ", response)
return response.data;
}, function (error) {
return Promise.reject(error);
});
// 默认情况下,axios将JavaScript对象序列化为JSON。 要以application / x-www-form-urlencoded格式发送数据,您可以使用以下选项之一。
const formEncoded = new URLSearchParams()
formEncoded.append("param01", "thisIsParam01")
formEncoded.append("param02", "thisIsParam02")
const rawForms = {
param01: "thisIsParam01",
param02: "thisIsParam02"
}
axios.request({
url: "/HelloWorld/listForm",
method: "post",
headers: {
"header01": "thisIsHeader01",
"header02": "thisIsHeader02",
'Content-Type': 'application/x-www-form-urlencoded'
},
data: formEncoded
})
.then(function (fullResp) {
// let resp = fullResp.data
let resp = fullResp
document.getElementById("resp").innerText = JSON.stringify(resp)
})
// axios.request({
// url: "/HelloWorld/listJson",
// method: "post",
// headers: {
// "header01": "thisIsHeader01",
// "header02": "thisIsHeader02",
// 'Content-Type': 'application/json'
// },
// data: {
// param01: "thisIsParam01",
// param02: "thisIsParam02"
// }
// })
// .then(function (fullResp) {
// //let resp = fullResp.data
// let resp = fullResp
// document.getElementById("resp").innerText = JSON.stringify(resp)
// })
</script>
</body>
</html>
处理以上请求的后端服务, 简单的处理, 获取到请求头 和 参数, 然后 响应给客户端?
通过 @RequesParam[request.getParameter("$paramName")], 或者 @RequestBody 来获取参数?
通过 @RequestHeader 来获取请求头?
/**
* HelloWorldController
*
* @author Jerry.X.He <970655147@qq.com>
* @version 1.0
* @date 2022-02-27 21:21
*/
@RestController
@RequestMapping("/HelloWorld")
public class HelloWorldController {
@RequestMapping("/listForm")
public List<JSONObject> listForm(
@RequestHeader("header01") String header01,
@RequestHeader("header02") String header02,
String param01,
String param02
) {
List<JSONObject> result = new ArrayList<>();
result.add(wrapEntity("header01", header01));
result.add(wrapEntity("header02", header02));
result.add(wrapEntity("param01", param01));
result.add(wrapEntity("param02", param02));
return result;
}
@RequestMapping("/listJson")
public List<JSONObject> listJson(
@RequestHeader("header01") String header01,
@RequestHeader("header02") String header02,
@RequestBody JSONObject param01
) {
List<JSONObject> result = new ArrayList<>();
result.add(wrapEntity("header01", header01));
result.add(wrapEntity("header02", header02));
result.add(wrapEntity("param01", JSON.toJSONString(param01)));
return result;
}
// wrapEntity
public JSONObject wrapEntity(String name, String age) {
JSONObject result = new JSONObject();
result.put("name", name);
result.put("age", age);
return result;
}
}
http 请求 和 http 响应
http 请求包含了三部分, 请求行, 请求头, 请求体?
请求行是第一行, 包含了 请求方法, uri, http协议版本?
请求行 和 请求头 通过 换行回车 分割, 接下来的 Host, Connection, 等等属于请求头?
请求体 和 请求头之间通过 两个换行回车分割, "param01=thisIsParam01¶m02=thisIsParam02" 属于请求体?
POST /HelloWorld/listForm HTTP/1.1
Host: localhost
Connection: keep-alive
Content-Length: 43
Pragma: no-cache
Cache-Control: no-cache
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="99", "Google Chrome";v="99"
header01: thisIsHeader01
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.45 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: */*
X-Requested-With: XMLHttpRequest
sec-ch-ua-platform: "macOS"
header02: thisIsHeader02
Origin: http://localhost
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost/httpClient/01Jquery.html
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7
Cookie: XXL_JOB_LOGIN_IDENTITY=7b226964223a312c22757365726e616d65223a2261646d696e222c2270617373776f7264223a226531306164633339343962613539616262653536653035376632306638383365222c22726f6c65223a312c227065726d697373696f6e223a6e756c6c7d
param01=thisIsParam01¶m02=thisIsParam02
http 响应包含了三部分, 状态行, 响应头, 响应体?
和上面 http 请求的结构类似, 不过状态行 是包含的是 http协议版本 加上 状态码?
HTTP/1.1 200
Server: nginx/1.19.9
Date: Mon, 28 Feb 2022 12:57:10 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
backendIP: 192.168.31.184:8080
b0
[{"name":"header01","age":"thisIsHeader01"},{"name":"header02","age":"thisIsHeader02"},{"name":"param01","age":"{\"param01\":\"thisIsParam01\",\"param02\":\"thisIsParam02\"}"}]
0
form表单 传递参数?
ajax 配置 contentType 为?application/x-www-form-urlencoded, 然后参数直接放到 data 中即可?
默认 jquery 会将参数处理为 表单参数格式
// When data is an object, jQuery generates the data string from the object's key/value pairs unless the processData option is set to false. For example, { a: "bc", d: "e,f" } is converted to the string "a=bc&d=e%2Cf"
$.ajax({
url: "/HelloWorld/listForm",
type: "POST",
contentType : "application/x-www-form-urlencoded",
headers : {
"header01" : "thisIsHeader01",
"header02" : "thisIsHeader02"
},
data : {
param01 : "thisIsParam01",
param02 : "thisIsParam02"
},
success: function (result) {
$("#resp").text(JSON.stringify(result))
}
});
发送给服务器的 http 请求为?
POST /HelloWorld/listForm HTTP/1.1
Host: localhost
Connection: keep-alive
Content-Length: 43
Pragma: no-cache
Cache-Control: no-cache
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="99", "Google Chrome";v="99"
header01: thisIsHeader01
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.45 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: */*
X-Requested-With: XMLHttpRequest
sec-ch-ua-platform: "macOS"
header02: thisIsHeader02
Origin: http://localhost
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost/httpClient/01Jquery.html
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7
Cookie: XXL_JOB_LOGIN_IDENTITY=7b226964223a312c22757365726e616d65223a2261646d696e222c2270617373776f7264223a226531306164633339343962613539616262653536653035376632306638383365222c22726f6c65223a312c227065726d697373696f6e223a6e756c6c7d
param01=thisIsParam01¶m02=thisIsParam02
浏览器中效果如下?
axios 这边默认是序列化为 json, 需要表单格式, 要表单格式的话, 需要手动转换[有 URLSearchParams 相关api]
// 默认情况下,axios将JavaScript对象序列化为JSON。 要以application / x-www-form-urlencoded格式发送数据,您可以使用以下选项之一。
const formEncoded = new URLSearchParams()
formEncoded.append("param01", "thisIsParam01")
formEncoded.append("param02", "thisIsParam02")
const rawForms = {
param01: "thisIsParam01",
param02: "thisIsParam02"
}
axios.request({
url: "/HelloWorld/listForm",
method: "post",
headers: {
"header01": "thisIsHeader01",
"header02": "thisIsHeader02",
'Content-Type': 'application/x-www-form-urlencoded'
},
data: formEncoded
})
.then(function (fullResp) {
// let resp = fullResp.data
let resp = fullResp
document.getElementById("resp").innerText = JSON.stringify(resp)
})
发送给服务器的 http 请求为?
POST /HelloWorld/listForm HTTP/1.1
Host: localhost
Connection: keep-alive
Content-Length: 43
Pragma: no-cache
Cache-Control: no-cache
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="99", "Google Chrome";v="99"
header01: thisIsHeader01
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.45 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: application/json, text/plain, */*
sec-ch-ua-platform: "macOS"
header02: thisIsHeader02
Origin: http://localhost
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost/httpClient/02Axios.html
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7
Cookie: XXL_JOB_LOGIN_IDENTITY=7b226964223a312c22757365726e616d65223a2261646d696e222c2270617373776f7264223a226531306164633339343962613539616262653536653035376632306638383365222c22726f6c65223a312c227065726d697373696f6e223a6e756c6c7d
param01=thisIsParam01¶m02=thisIsParam02
浏览器中效果如下?
application/json 传递参数?
ajax 配置 contentType 为?application/json,??默认 jquery 会将参数处理为 表单参数格式, 所以需要将参数手动处理为 json 字符串, 这里是基于 JSON.stringify?
$.ajax({
url: "/HelloWorld/listJson",
type: "POST",
contentType: "application/json",
headers: {
"header01": "thisIsHeader01",
"header02": "thisIsHeader02"
},
data: JSON.stringify({
param01: "thisIsParam01",
param02: "thisIsParam02"
}),
success: function (result) {
$("#resp").text(JSON.stringify(result))
}
});
发送给服务器的 http 请求为?
POST /HelloWorld/listJson HTTP/1.1
Host: localhost
Connection: keep-alive
Content-Length: 53
Pragma: no-cache
Cache-Control: no-cache
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="99", "Google Chrome";v="99"
header01: thisIsHeader01
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.45 Safari/537.36
Content-Type: application/json
Accept: */*
X-Requested-With: XMLHttpRequest
sec-ch-ua-platform: "macOS"
header02: thisIsHeader02
Origin: http://localhost
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost/httpClient/01Jquery.html
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7
Cookie: XXL_JOB_LOGIN_IDENTITY=7b226964223a312c22757365726e616d65223a2261646d696e222c2270617373776f7264223a226531306164633339343962613539616262653536653035376632306638383365222c22726f6c65223a312c227065726d697373696f6e223a6e756c6c7d
{"param01":"thisIsParam01","param02":"thisIsParam02"}
浏览器中效果如下?
axios 这边默认是序列化为 json, 不用做任何转化?
axios.request({
url: "/HelloWorld/listJson",
method: "post",
headers: {
"header01": "thisIsHeader01",
"header02": "thisIsHeader02",
'Content-Type': 'application/json'
},
data: {
param01: "thisIsParam01",
param02: "thisIsParam02"
}
})
.then(function (fullResp) {
let resp = fullResp.data
// let resp = fullResp
document.getElementById("resp").innerText = JSON.stringify(resp)
})
发送给服务器的 http 请求为?
POST /HelloWorld/listJson HTTP/1.1
Host: localhost
Connection: keep-alive
Content-Length: 53
Pragma: no-cache
Cache-Control: no-cache
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="99", "Google Chrome";v="99"
header01: thisIsHeader01
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.45 Safari/537.36
Content-Type: application/json
Accept: application/json, text/plain, */*
sec-ch-ua-platform: "macOS"
header02: thisIsHeader02
Origin: http://localhost
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost/httpClient/02Axios.html
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7
Cookie: XXL_JOB_LOGIN_IDENTITY=7b226964223a312c22757365726e616d65223a2261646d696e222c2270617373776f7264223a226531306164633339343962613539616262653536653035376632306638383365222c22726f6c65223a312c227065726d697373696f6e223a6e756c6c7d
{"param01":"thisIsParam01","param02":"thisIsParam02"}
浏览器中效果如下?
axios 的拦截器?
呵呵 常规的拦截处理, 在发送请求之前对于请求的统一转换处理, 以及在收到响应之后, 对于响应的统一转换处理?
这里 response 拦截处理, 直接获取了 reponse.data, 那么业务这边拿到的就是?reponse.data?
// interceptors
axios.interceptors.request.use(function (config) {
// 拦截 request, 处理请求
console.log("do sth before send request, config : ", config)
return config;
}, function (error) {
return Promise.reject(error);
});
axios.interceptors.response.use(function (response) {
// 拦截 response, 处理响应
console.log("do sth before receive response, response : ", response)
return response.data;
}, function (error) {
return Promise.reject(error);
});
下面的 then, 回调处理 拿到的 fullResp 即为服务端返回的响应数据, 而不是 axios 本身封装的一层 响应实体了?
可以和上面没有加 axios 拦截器的场景进行参照对比一下?
axios.request({
url: "/HelloWorld/listJson",
method: "post",
headers: {
"header01": "thisIsHeader01",
"header02": "thisIsHeader02",
'Content-Type': 'application/json'
},
data: {
param01: "thisIsParam01",
param02: "thisIsParam02"
}
})
.then(function (fullResp) {
// let resp = fullResp.data
let resp = fullResp
document.getElementById("resp").innerText = JSON.stringify(resp)
})
整个网关流程梳理
本测试用例基于 nginx 来提供前端服务, 以及代理后端服务?
nginx 服务器的 docker-compose 如下, 配置了容器中的 root目录 挂载在 宿主机的 "/Users/jerry/WebstormProjects/HelloWorld", 然后 "http://localhost/httpClient/01Jquery.html" 访问的就是 "/Users/jerry/WebstormProjects/HelloWorld/httpClient/01Jquery.html"?
version: "2"
services:
nginx:
container_name: nginx
image: nginx:latest
ports:
- "80:80"
volumes:
- ./data:/etc/nginx
# - ./html:/usr/share/nginx/html
- /Users/jerry/WebstormProjects/HelloWorld:/usr/share/nginx/html
项目目录结构如下
nginx 配置文件如下?
root目录 对应的是容器中的?/usr/share/nginx/html, 对应于挂载在宿主机的?/Users/jerry/WebstormProjects/HelloWorld?
配置了 "/HelloWorld" 打头的服务, 转发到?192.168.31.184:8080, 也就是我们的后端服务?
上面测试的 "/HelloWorld/listForm",?"/HelloWorld/listJson" 都是会转发到?192.168.31.184:8080?
server {
listen 80;
listen [::]:80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location ~ /HelloWorld {
proxy_pass http://192.168.31.184:8080;
add_header backendIP $upstream_addr;
proxy_set_header SSL-Client-Cert $ssl_client_cert;
proxy_set_header name jerry;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
完
|