验证:web应用程序要遵循http协议

全栈测试笔记 / 2024-02-14 / 原文

 

说明

web server响应的格式必须要遵循http响应协议,否则浏览器或者其它客户端工具不能解析响应;另外,http请求协议已经由浏览器或者其它客户端工具帮我们封装好了。

这里我们直接通过socket写一个简单的server来演示。

 

get请求

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响应协议返回。

 

服务端打印内容:

 

修改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中可以看到响应头和响应体

服务端打印内容:

 

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()

 

浏览器请求结果:

 

服务端打印内容:

 

post请求

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()

 

入参格式:application/x-www-form-urlencoded

请求

 

服务端打印内容:

 

工具中请求头

 

工具中请求体

 

响应头

 

响应体

 

入参格式: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响应体