前端三剑客之HTML
一、http协议
1、http 超文本传输协议
HTTP(Hypertext Transfer Protocol)是一种用于在Web上传输数据的协议,规定了服务端和客户端之间的数据传输格式及其标准。
HTTP协议是一种应用层协议,它是基于TCP/IP协议开发的。HTTP在TCP之上,而TCP在IP之上,形成了一个层次化的协议栈,这种组合允许HTTP协议通过互联网进行通信。HTTP协议负责定义客户端和服务器之间请求和响应的格式和规则,而TCP和IP协议负责确保数据包的可靠传输和路由。
服务端
import socket server = socket.socket() server.bind(("127.0.0.1", 8080)) server.listen(5) while True: conn, addr = server.accept() data = conn.recv(8096) conn.send(b"HTTP/1.1 200 OK\r\n\r\n") conn.send(b"<h1>Hello world!</h1>") conn.close()
浏览器客户端访问
服务端发来的数据要符合http协议要求
2、http协议的五大特性
请求-响应模型(Request-Response)
HTTP协议采用客户端-服务器模型,客户端发送请求到服务器,服务器处理请求并返回响应给客户端。
短连接(Connectionless)
HTTP协议是一种无连接的协议,即每个请求和响应都是独立的,服务器在完成客户端请求的响应后,立即断开连接。这样的特性使得服务器能够处理大量的请求,而不需要长时间保持连接状态,从而节省服务器资源。
无状态(Stateless)
HTTP协议是无状态的,即服务器不会保存之前请求的任何信息。每个请求都是独立的,服务器不能识别请求是否来自同一个客户端或之前的请求历史。这使得服务器设计简单,并且能够更好地扩展,但同时也要求在需要保持状态的应用场景下使用额外的机制,如Cookie或Session。
支持多媒体(Media-independent)
HTTP协议不仅仅支持传输HTML文本,还可以传输各种类型的数据,包括图片、音频、视频、文件等。这使得HTTP成为一个通用的应用层协议,可以用于传输各种不同类型的数据。
长连接( Keep-Alive)连接
-
减少连接建立和断开的开销:TCP连接的建立和断开会消耗一定的时间和资源,通过使用长连接,可以减少这些开销,从而提高性能和响应速度。
-
减少服务器负担:长连接使得服务器可以处理多个请求,而不必为每个请求建立新的连接。这在高并发的情况下特别有用,可以减轻服务器的负担。
-
并行传输:由于长连接可以在同一时间内传输多个请求和响应,客户端可以并行发送多个请求,而不必等待每个请求的响应。这有助于提高页面加载速度和资源获取效率。
虽然长连接可以提供更高的性能和效率,但它也需要服务器维护打开的连接,并在适当的时候关闭空闲连接,以防止资源浪费和连接过多导致的问题。为了解决长连接中的潜在问题,HTTP/1.1引入了"Connection: keep-alive"头部来明确指示使用长连接。在HTTP/1.1中,默认情况下,连接都是持久的,除非显式地指定"Connection: close"头部,以关闭连接。
值得注意的是,HTTP/2及更高版本使用了全新的多路复用技术,不再依赖于长连接来实现并行传输,因此在HTTP/2中,长连接的意义不同于HTTP/1.1时代。
3、http 协议的请求数据格式
常用的版本号就是http1.X版本,新版本应该是http2.x
请求首行(请求方式、协议/版本号)
请求头
\r\n
请求体(不是什么请求方式都有的,GET请求方式没有)
<Method> <Request-URI> <HTTP-Version> <Headers> <Optional Request Body>
4、HTTP协议的响应数据格式
响应首行(响应状态码)
响应头
\r\n
响应体
<HTTP-Version> <Status-Code> <Reason-Phrase> <Headers> <Optional Response Body>
5、请求方式(重要)
GET
用于请求获取指定资源的数据
协议:// 域名/后缀/?参数
协议:// 域名/后缀/?k=v&k1=v1&k2=v2...
POST
用于向服务器提交数据,通常用于创建新的资源。例如百度的登录功能,把用户名和密码提交到百度的后端做验证.用的就是POST请求
PUT
用于向服务器更新或替换指定资源的数据。PUT请求是幂等的,多次请求同一个URL应该产生相同的结果。
DELETE
用于请求服务器删除指定资源。DELETE请求是幂等的,多次请求同一个URL应该产生相同的结果。
PATCH
用于对资源进行部分更新,只传输需要修改的部分。PATCH请求是非幂等的。
HEAD
类似于GET请求,但服务器只返回响应头部信息,不返回实际数据。主要用于获取资源的元数据,比如资源是否存在、最后修改时间等。
OPTIONS
用于获取目标资源支持的请求方法和其他选项信息。
TRACE
用于追踪请求-响应的传输路径,主要用于调试和测试。
CONNECT
用于建立与代理服务器的隧道连接,通常用于代理服务器的身份验证。
6、get请求和post请求的区别
-
参数传递位置:
- GET请求:参数是通过URL的查询字符串传递的,在URL中以键值对的形式出现,例如:
http://www.example.com/page?param1=value1¶m2=value2
- POST请求:参数是通过请求体(Request Body)传递的,参数不会直接显示在URL中。
- GET请求:参数是通过URL的查询字符串传递的,在URL中以键值对的形式出现,例如:
-
安全性:
- GET请求:参数在URL中明文显示,因此不适合传递敏感信息,比如密码等。GET请求可以被缓存、浏览器历史记录等留存,可能会暴露敏感信息。
- POST请求:参数在请求体中传递,不会明文显示在URL中,相对于GET请求更安全,适合传递敏感信息。
-
请求体:
- GET请求:没有请求体,因为参数是在URL中传递的。
- POST请求:有请求体,参数包含在请求体中,格式可以是多种类型,比如JSON、表单数据等。
-
请求长度限制:
- GET请求:受浏览器和服务器限制,一般有长度限制,较大的数据可能会被截断。
- POST请求:没有固定的长度限制,可以传输大量数据。
-
幂等性:
- GET请求:通常是幂等的,多次请求同一个URL应该返回相同的结果。
- POST请求:不一定是幂等的,多次请求同一个URL可能会产生不同的副作用。
-
使用场景:
- GET请求:适合用于获取资源,比如获取页面、图片等。
- POST请求:适合用于提交数据,比如表单提交、上传文件等。
二、html 基础(标签、属性)
1、
<title>你看我在哪里显示</title> # 标签顶部显示的内容 <link rel="stylesheet" href="css/my.css"> # 引入外部CSS 在pycharm中注释符号的快捷键是:ctrl + ?
<b>加粗</b> <i>斜体</i> <u>下划线</u> <s>删除</s> <p>段落标签</p> <h1>标题1</h1> <h2>标题2</h2> <h3>标题3</h3> <h4>标题4</h4> <h5>标题5</h5> <h6>标题6</h6> <!--换行--> <br> <!--水平线--> <hr>
块级元素 # 独占一行,不管自身有多大,他自己就占一行 h1标题标签都是 p标签 hr标签 行内元素(内联元素) # 自身文本有多大就占多大,不会独占一行 <b>加粗</b> <i>斜体</i> <u>下划线</u> <s>删除</s>
方式二:
双标签 <b>加粗</b> <i>斜体</i> <u>下划线</u> <s>删除</s> h1标题标签都是 p标签 单标签 hr标签 br img a
5、
一般用来'布局'使用
div它是块儿级元素,给页面占布局 span标签是行内元素,用来给文本内容占布局
<div>
标签:
<div>
标签是HTML中最常见的块级容器元素,用于创建一个分隔的区块,类似于一个盒子或容器,可用于组织页面结构和布局。- 它是一个块级元素,意味着它会在页面中自动占据一整行,除非通过CSS样式指定宽度。
<div>
标签通常用于将一组相关的元素或内容包裹在一起,从而使它们能够受到共同的样式和布局控制。通过为<div>
标签添加id
或class
属性,可以为它们添加特定的样式或在JavaScript中对它们进行操作。
<div id="header"> <h1>Welcome to our website</h1> <p>Explore our services and products.</p> </div>
<span>
标签:
<span>
标签是HTML中常见的行内容器元素,用于在文本中标记或包裹特定的文本片段,而不会破坏文本的行内流动性。- 它是一个行内元素,意味着它只占据它所包裹内容的宽度,不会强制换行。
<span>
标签通常用于对文本进行样式化或添加特定的样式类。通过为<span>
标签添加id
或class
属性,可以为它们添加特定的样式或在JavaScript中对它们进行操作。
<p> Please enter your <span class="highlight">username</span> and <span class="highlight">password</span>. </p>
6、标签的嵌套
# 我们使用亲戚关系来表示标签之间的关系 <div> div标签是p标签的父标签 <p> p标签是div标签的儿子,是span标签的父标签 <span></span> span标签是p的儿子,是div的孙子 </p> <p></p> # p标签是div标签的儿子,是p标签的兄弟,也是span的兄弟标签 <span></span> </div>
注意事项:
- 块级元素能够嵌套所有的行内元素,块级元素也能够嵌套所有的块级元素(除了p标签之外)
- 行内元素不能嵌套块级元素,但是可以嵌套所有的行内元素
- 浏览器一般不会轻易报错,当
<p>
标签嵌套在块级元素中时,浏览器通常会自动尝试纠正错误,并在显示时进行一些处理,
三、常见标签的用法
1、、标签的两个重要属性和自定义属性
id 和 class 属性(重要)
id属性:
id
属性用于为HTML元素指定唯一的标识符。每个HTML文档中的id
值应该是唯一的,不能在同一文档中重复使用。您可以使用
id
属性来标识一个特定的元素,以便在CSS样式表中通过#idValue
选择器或JavaScript中通过document.getElementById('idValue')
方法来选择和修改该元素的样式或内容。
示例:
<div id="header"> <h1>Welcome to our website</h1> </div>
在这个例子中,div
元素被赋予了一个唯一的id
值为header
,这样我们就可以通过#header
选择器来样式化或操作这个div
元素。
class属性:
class
属性用于为HTML元素指定一个或多个样式类的名称。相对于id
属性,class
属性可以在同一文档中多次重复使用,因此一个HTML文档中可以有多个元素具有相同的class
值。使用
class
属性可以将相同样式应用于多个元素,也可以在CSS样式表中通过.className
选择器或JavaScript中通过document.getElementsByClassName('className')
方法来选择和修改一组具有相同类名的元素。
<ul> <li class="item">Item 1</li> <li class="item">Item 2</li> <li class="item">Item 3</li> </ul>
在这个例子中,三个li
元素都被赋予了相同的class
值为item
,这样我们就可以通过.item
选择器来样式化或操作这些li
元素。
自定义属性
<div id="d1" username='kevin' password='123'></div>
属性名可以自己来定,自定义属性一般用来存储数据的
2、img 标签(图片)
<img src="img/123.png" alt="你看我是什么东西" width="800px" height="200px">
src:写图片的地址(外链地址或本地地址)
alt:当图片加载失败时,显示描述信息
width和height是自定义属性,控制图片的大小,等比例缩放
3、a 标签(超链接)
<a href="https://th.bing.com/th/id/KP6X&pid=ImgRaw&r=0" title=西藏好地方 target="_blank">点我看西藏</a>
href是超链接地址(外链地址或本地地址)
title是鼠标悬停的时候显示的文字
target:_blank:浏览器新开一个标签页 _self : 当前页打开
4、列表
无序列表
<ul type="disc"> <li>第一个</li> <li>第一个</li> <li>第一个</li> <li>第一个</li> <li>第一个</li> <li>第一个</li> <li>第一个</li> </ul> type属性: ● disc(实心圆点,默认值) ● circle(空心圆圈) ● square(实心方块) ● none(无样式)
补充:ul>li{$}*5 快速生成5个无序标题
<ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul>
有序列表
<ol type="I" start="3"> <li>第一个</li> <li>第一个</li> <li>第一个</li> <li>第一个</li> <li>第一个</li> <li>第一个</li> <li>第一个</li> </ol> type属性: ● 1 数字列表,默认值 ● A 大写字母 ● a 小写字母 ● Ⅰ大写罗马 ● ⅰ小写罗马
补充:list-style: none;
属性用于移除HTML列表(<ul>
无序列表和<ol>
有序列表)的默认样式,比如默认的项目符号或数字。
再利用浮动特效,使得两个块元素可以放在一行
<style> * { margin: 0; padding: 0; } #d3 ul li { list-style: none; /*移除原有的有序或者无序的默认样式*/ float: left; /* 浮动特效 */ font-size: 10px; margin-right: 10px; margin-left: 8px; margin-top: 12px; color: #b0b0b0; height: 40px; }
列表的标题
<dl> <dt>标题1</dt> <dd>内容1</dd> <dt>标题2</dt> <dd>内容1</dd> <dd>内容2</dd> </dl>
5、表格(重要!!)
table thead (表头) tr----->代表一行 td(th)------>代表的是一列 tbody (内容) tr----->代表一行 td------>代表的是一列 属性: ● border: 表格边框. ● cellpadding: 内边距 ● cellspacing: 外边距. ● width: 像素 百分比.(最好通过css来设置长宽) ● rowspan: 单元格竖跨多少行 ● colspan: 单元格横跨多少列(即合并单元格)
案例:
<table border="10" cellpadding="5" cellspacing="10"> <thead> <tr> <td>id</td> <td>name</td> <td>age</td> <td>gender</td> <td>salary</td> </tr> </thead> <tbody> <tr> <td>1</td> <td>kevin</td> <td>18</td> <td>male</td> <td>2000</td> </tr> <tr> <td>1</td> <td>kevin</td> <td>18</td> <td>male</td> <td>2000</td> </tr> <tr> <td>1</td> <td>kevin</td> <td>18</td> <td>male</td> <td>2000</td> </tr> <tr> <td>1</td> <td colspan="3">kevin</td> <td rowspan="2">male</td> <td>2000</td> </tr> <tr> <td>1</td> <td>kevin</td> <td>18</td> <td>2000</td> </tr> </tbody> </table>
效果
注意:<table border="10" cellpadding="5" cellspacing="10"> 三个参数边框、内边距、外边距已经废弃,不推荐使用
使用CSS 样式进行控制
<!DOCTYPE html> <html lang="en"> <head> <style> /* 设置表格外边框 */ table { border-collapse: collapse; border: 2px solid black; /* 可根据需要调整边框宽度和颜色 */ width: 40%; /* 让表格填充父容器宽度 */ } /* 设置表头的背景颜色和字体样式,并居中显示文本 */ th { background-color: #f2f2f2; /* 可根据需要调整表头背景颜色 */ font-weight: bold; /* 加粗字体 */ font-size: 16px; /* 可根据需要调整字体大小 */ text-align: center; /* 居中显示文本 */ } /* 设置表格数据行的背景交替颜色 */ tr:nth-child(even) { background-color: #f9f9f9; /* 可根据需要调整偶数行背景颜色 */ } /* 设置单元格的内边距和字体样式,并居中显示文本 */ td, th { padding: 10px; /* 可根据需要调整内边距大小 */ font-size: 14px; /* 可根据需要调整字体大小 */ font-family: Arial, sans-serif; /* 可根据需要调整字体样式 */ text-align: center; /* 居中显示文本 */ } </style> </head> <body> <table> <tr> <th>id</th> <th>name</th> <th>age</th> <th>gender</th> <th>salary</th> </tr> <tr> <td>1</td> <td>kevin</td> <td>18</td> <td>male</td> <td>2000</td> </tr> <tr> <td>1</td> <td>kevin</td> <td>18</td> <td>male</td> <td>2000</td> </tr> <tr> <td>2</td> <td>kevin</td> <td>18</td> <td>male</td> <td>2000</td> </tr> <tr> <td>3</td> <td>kevin</td> <td>18</td> <td>male</td> <td>2000</td> </tr> <tr> <td>4</td> <td>kevin</td> <td>18</td> <td>male</td> <td>2000</td> </tr> </table> </body> </html>
6、form 表单(‼️)
<form>
表单元素用于创建用户交互的表单。表单通常用于收集用户提交的数据,例如登录信息、注册信息、搜索查询等。
<form>
元素可以包含各种表单元素,如文本输入框、单选按钮、复选框、下拉列表等,以及提交按钮。
<form></form> <label></label> # 通过id值绑定 <label for="username">用户名</label> <input type="text" id="username"> input: 通过改变input的属性type来达到不同的输入类型 text 单行输入文本 <input type=text" /> password 密码输入框 <input type="password" required placeholder="请输入密码"> date 日期输入框 <input type="date" /> checkbox 复选框 <input type="checkbox" checked="checked" /> radio 单选框 <input type="radio" /> submit 提交按钮 <input type="submit" value="提交" /> reset 重置按钮 <input type="reset" value="重置" /> button 普通按钮 <input type="button" value="普通按钮" /> hidden 隐藏输入框 <input type="hidden" /> file 文本选择框 <input type="file" /> 属性说明: ● name:表单提交时的“键”,注意和id的区别 ● value:表单提交时对应项的值 ○ type="button", "reset", "submit"时,为按钮上显示的文本年内容 ○ type="text","password","hidden"时,为输入框的初始值 ○ type="checkbox", "radio", "file",为输入相关联的值 ● checked:radio和checkbox默认被选中的项 ● readonly:text和password设置只读 ● disabled:所有input均适用 # 每一个单选框、复选框标签都应该有一个属性叫name <input type="submit" value="登录"> # 把前端数据提交表单到后端 <input type="button" value="登录"> # 不能够提交表单,就是一个空白的按钮,事件 <button>登录</button> # 提交表单的功能,但是,必须写在form表单里 <form action="" method="post"> <select name="city" id="city"> <option value="1">北京</option> <option selected="selected" value="2">上海</option> <option value="3">广州</option> <option value="4">深圳</option> </select> </form> 属性说明: ● multiple:布尔属性,设置后为多选,否则默认单选 ● disabled:禁用 ● selected:默认选中该项 ● value:定义提交时的选项值
-
name
属性:name
属性用于标识表单字段的名称,这个名称在提交表单时将作为数据的键名传递给服务器。- 每个表单字段(如输入框、复选框、单选按钮等)都应该有一个唯一的
name
属性。 - 通过
name
属性,服务器端脚本或后端应用程序可以识别和获取相应的表单数据。 - 在 HTML 表单中,表单字段的
name
属性通常结合服务器端代码来处理表单数据,例如 PHP、ASP.NET、Node.js 等。
-
value
属性:value
属性定义表单字段的初始值,或者在用户输入数据后,将包含用户输入的值。- 对于文本输入框、密码框、文本区域等,
value
属性设置默认文本或用户已输入的文本。 - 对于单选按钮和复选框,
value
属性指定了该选项提交时传递给服务器的值。 - 对于下拉菜单(
<select>
元素),value
属性指定每个选项的值。 - 用户在表单字段中输入的数据将会覆盖
value
属性中设置的默认值。
关于submit和button的区别补充
在HTML中,<submit>
和 <button>
都是用于在表单中创建按钮元素的标签,但它们在功能和用法上有一些区别。
<button>
在form表单中:需要将 type
属性设置为 "submit"
,则它将自动具有提交表单的功能,无需添加额外的 JavaScript 代码。
-
功能:
<input type="submit">
:submit是一个表单提交按钮。当用户点击这个按钮时,表单中的数据将被提交到服务器进行处理。<button>
:button是一个通用按钮,可以用于多种目的,不仅限于表单提交。您可以在按钮内部放置文本、图像或其他内容,然后使用JavaScript来定义按钮的点击行为。
-
默认行为:
<input type="submit">
:默认情况下,当用户点击这个按钮时,表单中的数据将被提交到与表单的action
属性相应的服务器端脚本。<button>
:默认情况下,按钮没有特定的行为。您需要使用JavaScript来为按钮添加交互行为,例如点击按钮时触发函数或执行其他操作。
-
用法:
<input type="submit">
:通常用于作为表单的主要提交按钮,以便将表单数据发送到服务器。<button>
:可以用于各种场景,不仅限于表单提交。您可以在按钮内部使用文本、图像、图标等来创建自定义按钮样式,然后使用JavaScript来添加所需的行为。
-
自定义内容:
<input type="submit">
:在这种情况下,按钮的显示文本通常由浏览器根据语言设置自动生成(例如,“Submit”或“提交”)。<button>
:您可以在按钮内部放置自定义的HTML内容,包括文本、图像等。
关于input text类型的补充
效果1: value
属性值,如果需要在表单提交时包含默认文本,需要使用value
属性来设置默认值。
效果2: placeholder
属性值,提供简短的提示信息,可以用于告知用户该输入框的预期内容或格式。请注意,这个属性并不会作为实际的表单值提交,它只是一个视觉上的提示,当用户提交表单时,它会被自动清除。
四、使用flask 框架做后端,数据存入mysql中
1、客户端用户提交页面html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Form 表单</title> </head> <body> <!-- 使用 form 元素创建一个表单 --> <form action="http://127.0.0.1:5000/index" method="post" enctype="multipart/form-data"> <!-- 表单内的表单元素 --> <p> <!-- 文本输入框 --> <label for="username">用户名:</label> <input type="text" id="username" name="username" required> <!-- "name" 属性用于标识输入框的名称,用于在提交表单时识别输入的数据 --> </p> <p> <!-- 密码输入框 --> <label for="password">密码:</label> <input type="password" id="password" name="password" required placeholder="请输入密码"> </p> <!--时间选择按钮--> <p> <input type="date" name="time"> </p> <p> <!-- 单选按钮 --> <label>性别:</label> <!-- <label for="male">Male</label>--> <input type="radio" id="male" name="gender" value="male"> 男 <!-- <label for="female">Female</label>--> <input type="radio" id="female" name="gender" value="female"> 女 <input type="radio" id="shuangxing" name="gender" value="shuangxing"> 未知 </p> <!-- 复选框 --> <p> <label>成年男子爱好:</label> <!-- checked 属性 表示默认为选中--> <input type="checkbox" name="hobby" value="洗脚"> 洗脚 <input type="checkbox" name="hobby" checked value="按摩"> 按摩 <input type="checkbox" name="hobby" checked value="喝酒"> 喝酒 <input type="checkbox" name="hobby" value="钓鱼"> 钓鱼 </p> <p> <!-- 下拉列表 --> <!-- for 属性用于将 <label> 元素与表单控件关联起来。通过将 for 属性设置为与表单控件的 id 属性相同的值,--> <!-- 用户就可以通过单击标签文本来触发相关的表单控件,从而提高表单的可用性和可访问性。--> <label for="city">城市:</label> <select id="city" name="city"> <!-- selected 表示默认选择北京--> <option value="BeiJing" selected>北京</option> <option value="ShangHai">上海</option> <option value="ChengDu">成都</option> </select> </p> <!-- 上传文件--> <p> <input type="file" name="myfile"> </p> <!-- 评论框--> <p> <label for="plq">评论区:</label> <br> <textarea name="textarea" id="plq" cols="20" rows="10"></textarea> </p> <!--当用户提交表单时,这个隐藏字段的值将与其他输入字段的值一起发送到服务器端,以便服务器进行相应的处理。--> <p> <input type="hidden" id="user_id" name="user_id" value="12345"> </p> <p> <!-- <input type="submit" value="登录">--> <!-- <input type="button" value="登录">--> <!-- 提交按钮 --> <button type="submit">登录</button> <input type="reset" value="重置"> </p> </form> </body> </html>
2、准备数据库
创表
CREATE TABLE user ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL, password VARCHAR(20) NOT NULL, subtime DATETIME, gender ENUM('male', 'female') DEFAULT 'male', hobby VARCHAR(50), city VARCHAR(20) );
配置mysql8远程登录
root@127.0.0.1:(none)> CREATE USER 'root'@'%' IDENTIFIED BY 'PASSWORD'; Query OK, 0 rows affected Time: 0.006s root@127.0.0.1:(none)> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION; Query OK, 0 rows affected Time: 0.005s root@127.0.0.1:(none)> FLUSH PRIVILEGES; Query OK, 0 rows affected Time: 0.004s MySQL root@127.0.0.1:(none)> ALTER USER 'root'@'%' IDENTIFIED BY 'Zjz5740##'; You're about to run a destructive command. Do you want to proceed? (y/n): y Your call!
测试
INSERT INTO user (username, password, subtime, gender, hobby, city) VALUES ('JohnDoe', 'password123', '2023-07-18 00:00:00', 'male', 'reading, write', 'New York');
3、服务端接收数据并存到mysql中
from flask import Flask, request import pymysql app = Flask(__name__) @app.route('/index/', methods=['GET', 'POST']) def index(): try: data = request.form username = data.get('username') password = data.get('password') time = data.get('time') gender = data.get('gender') hobby = data.getlist('hobby') city = data.get('city') conn = pymysql.connect( host='127.0.0.1', port=3306, user='root', passwd='Zjz740##', database='html', charset='utf8mb4', autocommit=True ) cursor = conn.cursor() sql = "INSERT INTO user(username, password, subtime, gender, hobby, city) VALUES (%s, %s, %s, %s, %s, %s)" cursor.execute(sql, (username, password, time, gender, ', '.join(hobby), city)) file_obj = request.files.get('myfile') if file_obj: file_obj.save(file_obj.filename) cursor.close() conn.close() return 'OK' except Exception as e: print(str(e)) return 'Internal Server Error: ' + str(e), 500 if __name__ == "__main__": app.run()