验证:web应用程序要遵循http协议
关于http协议
详见:https://www.cnblogs.com/uncleyong/p/18015084
web server响应的格式必须要遵循http响应协议,否则浏览器或者其它客户端工具不能解析响应;另外,http请求协议已经由浏览器或者其它客户端工具帮我们封装好了。
这里我们直接通过socket写一个简单的server来演示。
响应格式不遵循http响应协议
server.py
import socket import time # 创建TCP Socket对象;括号中的实参是默认值,可以简写为:sock = socket.socket() sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定IP地址和端口号 host = '127.0.0.1' port = 8089 sock.bind((host, port)) # 开始监听连接 sock.listen(5) print('等待客户端连接...') while True: # 接受客户端连接并返回新的Socket对象 conn, addr = sock.accept() # 阻塞等待客户端连接 # print('与客户端', addr[0], '建立了连接!') # 接收客户端发送的请求数据,接收最多4096字节大小的请求数据,然后将其转换成UTF-8编码格式的字符串 data = conn.recv(4096) # data = conn.recv(4096).decode("utf-8") print('接收到的请求数据为:', data) # 服务端返回数据 conn.send(b'hello, qzcsbj') print('返回数据给客户端完成') # 关闭当前客户端连接 conn.close()
浏览器请求后,浏览器无法解析服务器响应的内容,因为响应内容没有按照http响应协议返回。
服务端打印内容:
响应格式遵循http响应协议及响应头中的content-type
返回text/plain
修改server.py返回内容,其中content-type是text/plain;charset=utf-8,是纯文本,不做解析
import socket # 创建TCP Socket对象;括号中的实参是默认值,可以简写为:sock = socket.socket() sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定IP地址和端口号 host = '127.0.0.1' port = 8089 sock.bind((host, port)) # 开始监听连接 sock.listen(5) print('等待客户端连接...') while True: # 接受客户端连接并返回新的Socket对象 conn, addr = sock.accept() # 阻塞等待客户端连接 # print('与客户端', addr[0], '建立了连接!') # 接收客户端发送的请求数据,接收最多4096字节大小的请求数据,然后将其转换成UTF-8编码格式的字符串 data = conn.recv(4096) # data = conn.recv(4096).decode("utf-8") print('接收到的请求数据为:', data) # 服务端返回数据 conn.send('HTTP/1.1 200 ok\r\nserver:qzcsbj\r\ncontent-type:text/plain;charset=utf-8\r\n\r\n<h1>hello, 韧</h1>'.encode("utf-8")) print('返回数据给客户端完成') # 关闭当前客户端连接 conn.close()
浏览器请求结果:
F12中可以看到响应头和响应体
服务端打印内容:
返回text/html
server.py中,content-type是text/html;charset=utf-8,是html,按html解析
import socket # 创建TCP Socket对象;括号中的实参是默认值,可以简写为:sock = socket.socket() sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定IP地址和端口号 host = '127.0.0.1' port = 8089 sock.bind((host, port)) # 开始监听连接 sock.listen(5) print('等待客户端连接...') while True: # 接受客户端连接并返回新的Socket对象 conn, addr = sock.accept() # 阻塞等待客户端连接 # print('与客户端', addr[0], '建立了连接!') # 接收客户端发送的请求数据,接收最多4096字节大小的请求数据,然后将其转换成UTF-8编码格式的字符串 data = conn.recv(4096) # data = conn.recv(4096).decode("utf-8") print('接收到的请求数据为:', data) # 服务端返回数据 conn.send('HTTP/1.1 200 ok\r\nserver:qzcsbj\r\ncontent-type:text/html;charset=utf-8\r\n\r\n<h1>hello, 韧</h1>'.encode("utf-8")) print('返回数据给客户端完成') # 关闭当前客户端连接 conn.close()
浏览器请求结果:
服务端打印内容:
返回json
server.py
import socket # 创建TCP Socket对象;括号中的实参是默认值,可以简写为:sock = socket.socket() sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定IP地址和端口号 host = '127.0.0.1' port = 8089 sock.bind((host, port)) # 开始监听连接 sock.listen(5) print('等待客户端连接...') while True: # 接受客户端连接并返回新的Socket对象 conn, addr = sock.accept() # 阻塞等待客户端连接 # print('与客户端', addr[0], '建立了连接!') # 接收客户端发送的请求数据,接收最多4096字节大小的请求数据,然后将其转换成UTF-8编码格式的字符串 data = conn.recv(4096) # data = conn.recv(4096).decode("utf-8") print('接收到的请求数据为:', data) # 服务端返回数据 conn.send('HTTP/1.1 200 ok\r\nserver:qzcsbj\r\ncontent-type:application/json\r\n\r\n{"code":0,"message":"success","data":{"id":"1","name":"韧"}}'.encode("utf-8")) print('返回数据给客户端完成') # 关闭当前客户端连接 conn.close()
浏览器请求
postman请求
如果返回的content-type改为纯文本:
conn.send('HTTP/1.1 200 ok\r\nserver:qzcsbj\r\ncontent-type:text/plain\r\n\r\n{"code":0,"message":"success","data":{"id":"1","name":"韧"}}'.encode("utf-8"))
postman请求,哪怕是json格式字符串,也不会json格式化展示
补充:关于请求数据中的content-type
服务器根据接收到请求数据中的content-type来解析请求体数据
post请求入参格式:application/x-www-form-urlencoded
请求
服务端打印内容:如果多个参数,以&拼接,比如name=ren&age=18
工具中请求头
工具中请求体
响应头
响应体
post请求入参格式:application/json
请求头
请求
服务端打印内容:
工具中请求头
工具中请求体
响应头
响应体
补充:如果请求数据包含中文
jmeter中要指定内容编码
代码中接收客户端请求数据,要打印查看,需要decode
import socket # 创建TCP Socket对象;括号中的实参是默认值,可以简写为:sock = socket.socket() sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定IP地址和端口号 host = '127.0.0.1' port = 8089 sock.bind((host, port)) # 开始监听连接 sock.listen(5) print('等待客户端连接...') while True: # 接受客户端连接并返回新的Socket对象 conn, addr = sock.accept() # 阻塞等待客户端连接 # print('与客户端', addr[0], '建立了连接!') # 接收客户端发送的请求数据,接收最多4096字节大小的请求数据,然后将其转换成UTF-8编码格式的字符串 # data = conn.recv(4096) data = conn.recv(4096).decode("utf-8") print('接收到的请求数据为:', data) # 服务端返回数据 conn.send('HTTP/1.1 200 ok\r\nserver:qzcsbj\r\ncontent-type:application/json\r\n\r\n{"code":0,"message":"success","data":{"id":"1","name":"韧"}}'.encode("utf-8")) print('返回数据给客户端完成') # 关闭当前客户端连接 conn.close()
服务端打印内容:
jmeter响应体
__EOF__
关于博主:擅长性能、全链路、自动化、企业级自动化持续集成(DevTestOps)、测开等
面试必备:项目实战(性能、自动化)、简历笔试,https://www.cnblogs.com/uncleyong/p/15777706.html
测试提升:从测试小白到高级测试修炼之路,https://www.cnblogs.com/uncleyong/p/10530261.html
欢迎分享:如果您觉得文章对您有帮助,欢迎转载、分享,也可以点击文章右下角【推荐】一下!