v对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。
先来看段程序
import socket def handle_request(client): buf = client.recv(1024) client.send(bytes("HTTP/1.1 200 OK ",encoding="utf8")) client.send(bytes("Hello, Seven",encoding="utf8")) def main(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('localhost', 8000)) sock.listen(5) while True: connection, address = sock.accept() handle_request(connection) connection.close() if __name__ == '__main__': main()
首先我们运行服务器,然后打开chrome,输入url:http://localhost:8000.此时我们能得到服务器的响应。
什么是 HTML?
HTML 是用来描述网页的一种语言。
- HTML 指的是超文本标记语言 (Hyper Text Markup Language)
- HTML 不是一种编程语言,而是一种标记语言 (markup language)
- 标记语言是一套标记标签 (markup tag)
- HTML 使用标记标签来描述网页
HTML 标签
HTML 标记标签通常被称为 HTML 标签 (HTML tag)。
- HTML 标签是由尖括号包围的关键词,比如 <html>
- HTML 标签通常是成对出现的,比如 <b> 和 </b>
- 标签对中的第一个标签是开始标签,第二个标签是结束标签
- 开始和结束标签也被称为开放标签和闭合标签
HTML 文档 = 网页
- HTML 文档描述网页
- HTML 文档包含 HTML 标签和纯文本
- HTML 文档也被称为网页
Web 浏览器的作用是读取 HTML 文档,并以网页的形式显示出它们。浏览器不会显示 HTML 标签,而是使用标签来解释页面的内容.我们也可以理解成html可以理解为一套规则,浏览器认识的规则,下面我们开始学习HTML规则。
首先我们通过pycharm生成一个html文件s1.html。可以看到自动帮我们生成如下代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> </body> </html>
下面介绍下这些函数的意义
<!DOCTYPE html> <!-- <!DOCTYPE html>声明为 HTML5 文档--> <html lang="en"> <!-- <html>元素是 HTML 页面的根元素,lang是html的属性,htmlb标签只能有一个,可以把html比成一个人--> <head> <!-- <head>元素包含了文档的元(meta)数据,head就是头--> <meta charset="UTF-8"> <!-- 声明编码,自闭合标签--> <title>Title</title> <!-- <title> 元素描述了文档的标题,主动闭合标签--> </head> <body><!-- <body> 元素包含了可见的页面内容,body就是身体--> </body> </html>
head标签
head标签中几种常用标签
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>head几种常用标签</title> <!--<meta http-equiv="Refresh" content="3"> <!– 3秒刷新一次网页–>--> <!--<meta http-equiv="Refresh" content = "2;Url=http://www.baidu.com"> <!– 跳转到url指定的网站–>--> <meta name = "keywords" content="lxj sx"><!-- 关键字,别人能跟据什么关键字搜到你的网页--> <meta name = "description" content = "个人简介"> <!-- 网页描述--> <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"> <!-- 网页以IE7标准模式打开,可以调整IE9,IE8 content ="IE=IE9;IE=IE8" --> </head> <body> </body> </html>
head还有几种标签,需要到CSS才能讲
1、<link />
2、<style />
3、< script>
其中link可以先讲以下title的图标显示
<link rel="shortcut icon" href="timg.jpg"> <!-- href 文件路径-->
body标签
1、特殊符号
<body> l > x j <!-- 空格 > 大于号--> </body>
更多详见http://www.cnblogs.com/web-d/archive/2010/04/16/1713298.html
2、p标签和br标签
p标签表示段落,自带特性换行,br标签表示换行
<body> <p> 123 </p> <p> 456 </p> <p> 789 </p> </body>
结果:
<body> <p> 123<br />abc<br /> def </p> <p> 456 </p> <p> 789 </p> </body>
总结,段落有空行,换行没有空行
3、h标签和span标签
h标签即标题,自带特性,加大加粗
span标签我们可以称为白板,有多少内容占多少内容,自身不带任何属性
<body> <h1>标题</h1> <h2>标题</h2> <h3>标题</h3> <h4>标题</h4> <h5>标题</h5> <h6>标题</h6> <span> 内容1 </span> <span> 内容2 </span> <span> 内容3 </span> </body>
4、div标签
div标签也可以称为白板,自身占一行,自身同span一样不带任何属性
<body> <div> 123 </div> <div> abc </div> <div> 456 </div> </body>
结果:
标签之间可以嵌套,不限于div标签
<div> 123 <div> abc </div> </div>
input系列
input系列之文本、密码、按钮、提交
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>input系列</title> </head> <body> <form><!--如果input要向后台提交数据,必须包含在表单中--> <input type="text" name="user"/> <!--type=text,输入文本--> <input type="password" name="pwd"/> <!--type=password,输入密码--> <input type="button" value="按钮"/> <!--type=button,按钮件,这里没有任何用处,在CSS中回赋予其它功能--> <input type="submit" value="提交"/> <!--type=submit,提交件,提交数据到后台--> </form> </body> </html>
此时我们用chrome调试可以看到如下界面
此时我们输入内容,点击提交,发现没有任何变化。
此时我们重新输入文本123 密码abc点击提交按钮,此时我们看到
此时我们看到,我们输入的内容拼接到url后面了。这里要提到了HTTP请求的两种方法,GET和POST。看这个结果显示默认GET请求。如果要使用POST请求,我们可以在表单中改成POST提交
<form method="post"> #对上面的form表单修改post方法
此时我们再看变化,发现点击提交按钮,URL也没有任何变化,这是因为我们把表单放在内容(content)中传到后台。下面看个与服务器交互的例子
#服务器 import tornado.web import tornado.ioloop class MainHandler(tornado.web.RequestHandler): def get(self, *args, **kwargs): user = self.get_argument("user") pwd = self.get_argument("pwd") if user == "lxj" and pwd == "123": self.write("GET OK") else: self.write("GET ERROR") def post(self): """ html中通过input提交到服务器的数据,是以name为key,输入内容为value的字典形式 :return: """ user = self.get_argument("user") pwd = self.get_argument("pwd") if user == "lxj" and pwd == "123": self.write("POST OK") else : self.write("POST ERROR") application = tornado.web.Application([ (r"/index",MainHandler), #如果传过来的url后面是/index,执行MainHandler对应的方法,post或则get ]) if __name__ == "__main__": application.listen(8000) tornado.ioloop.IOLoop.instance().start() #html文件 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>input系列</title> </head> <body> <form action="http://localhost:8000/index" method="post"><!--如果input要向后台提交数据,必须包含在表单中--> <input type="text" name="user"/> <!--type=text,输入文本,name属性是方便后台读取key,这里也有value属性,同button和submit的value不同,这里的value是显示默认值--> <input type="password" name="pwd"/> <!--type=password,输入密码,value属性同text--> <input type="button" value="按钮"/> <!--type=button,按钮件,这里没有任何用处,在CSS中回赋予其它功能。value按钮的内容--> <input type="submit" value="提交"/> <!--type=submit,提交件,提交数据到后台--> </form> </body> </html> #此时我们提交test:lxj pwd:123,就能得到POST OK的界面。这时我们用的是POST请求
下面模拟一次网页搜索,首先我们打开搜索,搜索名字,看到的URL是这样子的
现在用HTML模拟
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="https://www.sogou.com/web"> <input type="text" name="query"/> <input type="submit" value="搜索"/> </form> </body> </html>
input系列之单选框和复选框
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="http://localhost:8002/index"> <div> <p> 请选择性别: </p> 男:<input type="radio" name = "gender" value="man" checked="checked"/> 女:<input type="radio" name = "gender" value="women" /> <!--type= radio 为圆形选择框,一般用户单选框,name=gender,gender相当于key,如果都设置为同一个值,则表示同类型的框只能选择一个(一般都这么用),name设置为不同值时,可以多选,提交多个,value值--> <p> 爱好: </p> 篮球:<input type="checkbox" name = "hobby" value="basketball" /> 足球:<input type="checkbox" name = "hobby" value="football" /> 羽毛球:<input type="checkbox" name = "hobby" value="badminton" checked="checked"/> <!--type="checkbox" 方形多选框 ,提交到后台一般同一组操作使用相同的name(key),不同的value。后台读取时用self.get_arguments("hobby")(tornado为例),返回为列表形式--> <!-- checked="checked" 默认值--> </div> <span> <input type="submit" value="提交" /> </span> </form> </body> </html>
input系列之上传文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="http://localhost:8002/index" method="post" enctype="multipart/form-data"> <div> <p> 请选择性别: </p> 男:<input type="radio" name = "gender" value="man" checked="checked"/> 女:<input type="radio" name = "gender" value="women" /> <!--type= radio 为圆形选择框,一般用户单选框,name=gender,gender相当于key,如果都设置为同一个值,则表示同类型的框只能选择一个(一般都这么用),name设置为不同值时,可以多选,提交多个,value值--> <p> 爱好: </p> 篮球:<input type="checkbox" name = "hobby" value="basketball" /> 足球:<input type="checkbox" name = "hobby" value="football" /> 羽毛球:<input type="checkbox" name = "hobby" value="badminton" checked="checked"/> <!--type="checkbox" 方形多选框 ,提交到后台一般同一组操作使用相同的name(key),不同的value。后台读取时用self.get_arguments("hobby")(tornado为例),返回为列表形式--> <!-- checked="checked" 默认值--> <p> 上传文件 </p> <input type="file" name="file"> <!-- type="file" 上传文件,此时还提交不了服务器,必须依赖form表单的一个属性enctype="multipart/form-data"--> </div> <span> <input type="submit" value="提交" /> </span> </form> </body> </html>
服务器
import tornado.web import tornado.ioloop class MainHandler(tornado.web.RequestHandler): def get(self, *args, **kwargs): pass def post(self): """ html中通过input提交到服务器的数据,是以name为key,输入内容为value的字典形式 :return: """ file_metas = self.request.files["file"] # print(file_metas) for meta in file_metas: filename = meta['filename'] #读取文件名 with open(filename,"wb") as f: f.write(meta["body"]) #写入文件内容 application = tornado.web.Application([ (r"/index",MainHandler), #如果传过来的url后面是/index,执行MainHandler对应的方法,post或则get ]) if __name__ == "__main__": application.listen(8002) tornado.ioloop.IOLoop.instance().start()
input系列之重置
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="http://localhost:8002/index" method="post" enctype="multipart/form-data"> <div> <p> 请选择性别: </p> 男:<input type="radio" name = "gender" value="man" checked="checked"/> 女:<input type="radio" name = "gender" value="women" /> <!--type= radio 为圆形选择框,一般用户单选框,name=gender,gender相当于key,如果都设置为同一个值,则表示同类型的框只能选择一个(一般都这么用),name设置为不同值时,可以多选,提交多个,value值--> <p> 爱好: </p> 篮球:<input type="checkbox" name = "hobby" value="basketball" /> 足球:<input type="checkbox" name = "hobby" value="football" /> 羽毛球:<input type="checkbox" name = "hobby" value="badminton" checked="checked"/> <!--type="checkbox" 方形多选框 ,提交到后台一般同一组操作使用相同的name(key),不同的value。后台读取时用self.get_arguments("hobby")(tornado为例),返回为列表形式--> <!-- checked="checked" 默认值--> <p> 上传文件 </p> <input type="file" name="file"> <!-- type="file" 上传文件,此时还提交不了服务器,必须依赖form表单的一个属性enctype="multipart/form-data"--> </div> <input type="submit" value="提交" /> <input type="reset" value="重置" /> <!-- type="reset" 把数据恢复到初始状态--> </form> </body> </html>
textarea标签
textarea标签可以输入多行
<textarea name = "meno" >asds</textarea><!-- textarea可以输入多行,可以设置name作为提交后台的key,textarea标签中间输入的值是默认值-->
select标签
select标签是下拉框
<select name = "city"> <!-- select标签,下拉框,name提交到后台的key,value即提交后台的value--> <option value="beijing">北京</option> <option value="shanghai">上海</option> <option value="hangzhou">杭州</option> </select>
下面实现select另外一种方法,实现下拉框,并显示所有可选项,select包含multiple选项,可利用ctrl组合键选择多个。
<select name = "city" size = 4 multiple = "multiple"> <!-- select标签,size表示下拉框的大小,默认为1,multiple表示可选择多个--> <option value="beijing">北京</option> <option value="shanghai" selected = "selected">上海</option> <option value="hangzhou">杭州</option> </select>
<select name = "city" size = 4 multiple = "multiple"> <!-- select标签,下拉框 name提交到后台的key,value即提交后台的value--> <option value="beijing">北京</option> <option value="shanghai" selected = "selected">上海</option> <optgroup label="浙江省"> <!-- optgroup标签属性,不能选择--> <option value="hangzhou">杭州</option> <option value="hangzhou">衢州</option> </optgroup> </select>
a标签
a标签做为跳转使用。
<body> <a href="http://www.baidu.com" target="_blank"> <!--a标签,跳转,target="_blank"表示在新的页面跳转--> 百度 </a> </body>
a标签做为锚使用
<body> <a href = "#1"> 第一章</a> <!-- a标签做为锚点,href指向需为#加id号--> <a href = "#2"> 第二章</a> <a href = "#3"> 第三章</a> <a href = "#4"> 第四章</a> <div id = 1 style="height: 600px;">第一章的内容</div> <div id = 2 style="height: 600px;">第二章的内容</div> <div id = 3 style="height: 600px;">第三章的内容</div> <div id = 4 style="height: 600px;">第四章的内容</div> </body>
img标签
<a href="http://www.baidu.com"> <!--通过图片跳转,在a标签中插入img标签--> <img src = "timg.jpg" title="箭头" style="height: 200px; 200px;" alt = "箭头"> <!--img标签插入图片,title显示图片的概要,src图片地址,style设置图片大小 alt当无法显示图片时,显示alt的值--> </a>
几种列表显示形式
<body> <a href="http://www.baidu.com"> <!--通过图片跳转,在a标签中插入img标签--> <img src = "timg.jpg" title="箭头" style="height: 200px; 200px;" alt = "箭头"> <!--img标签插入图片,title显示图片的概要,src图片地址,style设置图片大小 alt当无法显示图片时,显示alt的值--> </a> <ul> <li>asdf</li> <li>asdf</li> <li>asdf</li> <li>asdf</li> </ul> <ol> <li>asdf</li> <li>asdf</li> <li>asdf</li> </ol> <dl> <dt>ttt</dt> <dd>1</dd> <dd>2</dd> <dd>3</dd> <dt>abc</dt> <dd>4</dd> <dd>5</dd> <dd>3</dd> </dl> </body>
表格
<body> <table border="1"> <!--<table>表格,tr表示行,td表示列 border="1"表示加上边框--> <tr> <td>第一行第一列</td> <td>第一行第二列</td> <td>第一行第三列</td> </tr> <tr> <td>第二行第一列</td> <td>第二行第二列</td> <td>第二行第三列</td> </tr> </table> </body>
表格规范写法
<table border="1"><!--<table>表格,thead表示头,tbody表示内容行--> <thead> <tr> <th>列1</th> <th>列2</th> <th>列3</th> <th>列4</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>2</td> <td>3</td> <td>4</td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> <td>4</td> </tr> </tbody> </table>
合并单元格
<table border="1"><!--<table>表格,thead表示头,tbody表示内容行--> <thead> <tr> <th>列1</th> <th>列2</th> <th>列3</th> <th>列4</th> </tr> </thead> <tbody> <tr> <td rowspan="2">1</td> <!--行合并单元格,即竖向合并单元格--> <td colspan="3">2</td> <!--列合并单元格,即横向合并单元格--> </tr> <tr> <td >1</td> <td>2</td> <td>3</td> </tr> </tbody> </table>
fieldset和lable标签
<body> <label for ="username">用户名:</label> <!--lable 标签一般搭配input使用 for用来获取光标 即点击该标签光标也能到输入文本框--> <input id = "username" type="text" name = "user"> </body>
<fieldset> <!--做一个登陆框 ,不常用 --> <legend>登陆</legend> <label for="username">用户名:</label> <!--lable 标签一般搭配input使用 for用来获取光标 即点击该标签光标也能到输入文本框--> <input id="username" type="text" name="user"> <br> <label for="username">密码:</label> <!--lable 标签一般搭配input使用 for用来获取光标 即点击该标签光标也能到输入文本框--> <input id="password" type="text" name="pwd"> </fieldset>