web应用和http协议

1、web应用

  Web应用程序是一种能够经过Web访问的应用程序;html

  程序的最大好处是用户很容易访问应用程序,用户只须要有浏览器便可,不须要再安装其余软件。java

  应用程序有两种模式C/S、B/Spython

  一、C/S是客户端/服务器端程序,也就是说这类程序通常独立运行。web

  二、B/S就是浏览器端/服务器端应用程序,这类应用程序通常借助谷歌,火狐等浏览器来运行。编程

  WEB应用程序通常是B/S模式。Web应用程序首先是“应用程序”,和用标准的程序语言,如java,python等编写出来的程序没有什么本质上的不一样。在网络编程的意义下,浏览器是一个socket客户端,服务器是一个socket服务端。浏览器

# -*- coding:utf-8 -*-
__author__ = 'Qiushi Huang'


import socket

sock = socket.socket()
sock.bind(("127.0.0.1", 8800))  # 服务器地址和端口
sock.listen(5)

while True:
    print("server waiting.......")
    # conn:客户端套接字对象,addr:
    conn, addr = sock.accept()  # 等待用户链接
    data = conn.recv(1024)
    print(data)

    # 响应首行(HTTP/1.1 200 OK)、响应体
    conn.send(b"HTTP/1.1 200 OK\r\n\r\n<h1>hello luffycity!</h1>")  # 通常都是须要两个空格分隔\r\n\r\n

    conn.close()

    """
    server waiting.......
    b'GET / HTTP/1.1\r\n
    Host: 127.0.0.1:8800\r\n
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:59.0) Gecko/20100101 Firefox/59.0\r\n
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n
    Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2\r\n
    Accept-Encoding: gzip, deflate\r\n
    Connection: keep-alive\r\nUpgrade-Insecure-Requests: 1
    \r\n\r\n'
    
    请求首行里有多个请求头,每一个请求头用\r\n进行区分。  直到出现\r\n\r\n时,后面的为请求体。

    get请求没有请求体,请求体是给post请求用的。
    """

2、web框架

  Web框架(Web framework)是一种开发框架,用来支持动态网站、网络应用和网络服务的开发。这大多数的web框架提供了一套开发和部署网站的方式,也为web行为提供了一套通用的方法。web框架已经实现了不少功能,开发人员使用框架提供的方法而且完成本身的业务逻辑,就能快速开发web应用了。浏览器和服务器的是基于HTTP协议进行通讯的。也能够说web框架就是在如下十几行代码基础张扩展出来的,有不少简单方便使用的方法,大大提升了开发的效率。缓存

import socket

def handle_request(client):

    request_data = client.recv(1024)
    print("request_data: ",request_data)
    client.send("HTTP/1.1 200 OK\r\n\r\n".encode("utf8"))
    client.send("<h1 style='color:red'>Hello, 路飞学城! </h1>".encode("utf8"))

def main():

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('localhost',8800))
    sock.listen(5)

    while True:
        print("the server is waiting for client-connection....")
        connection, address = sock.accept()
        handle_request(connection)
        connection.close()

if __name__ == '__main__':

    main()

3、http协议

一、HTTP协议简介

  HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于万维网(WWW:World Wide Web )服务器与本地浏览器之间传输超文本的传送协议。安全

HTTP是一个属于应用层的面向对象的协议,因为其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,通过几年的使用与发展,获得不断地完善和扩展。HTTP协议工做于客户端-服务端架构为上。浏览器做为HTTP客户端经过URL向HTTP服务端即WEB服务器发送全部请求。Web服务器根据接收到的请求后,向客户端发送响应信息。服务器

  

二、HTTP协议特色

  • 基于TCP/IP网络

  计算机与网络设备要相互通讯,双方就必须基于相同的方法。好比,如何探测到通讯目标、由哪一边先发起通讯、使用哪一种语言进行通 信、怎样结束通讯等规则都须要事先肯定。不一样的硬件、操做系统之间 的通讯,全部的这一切都须要一种规则。而咱们就把这种规则称为协议(protocol)。协议中存在各式各样的内容。从电缆的规格到IP地址的选定方法、 寻找异地用户的方法、双方创建通讯的顺序,以及Web页面显示须要 处理的步骤,等等。像这样把与互联网相关联的协议集合起来总称为TCP/IP。

  http协议是基于TCP/IP协议之上的应用层协议。

  • 基于请求——响应模式

  HTTP协议规定,请求从客户端发出,最后服务器端响应该请求并 返回。换句话说,确定是先从客户端开始创建通讯的,服务器端在没有 接收到请求以前不会发送响应。

  

  • 无状态保存

  HTTP是一种不保存状态,即无状态(stateless)协议。HTTP协议自身不对请求和响应之间的通讯状态进行保存。也就是说在HTTP这个级别,协议对于发送过的请求或响应都不作持久化处理 

  

  使用HTTP协议,每当有新的请求发送时,就会有对应的新响应产生。协议自己并不保留以前一切的请求或响应报文的信息。这是为了更快地处理大量事务,确保协议的可伸缩性,而特地把HTTP协议设计成 如此简单的。但是,随着Web的不断发展,因无状态而致使业务处理变得棘手的状况增多了。好比,用户登陆到一家购物网站,即便他跳转到该站的 其余页面后,也须要能继续保持登陆状态。针对这个实例,网站为了能 够掌握是谁送出的请求,须要保存用户的状态。HTTP/1.1虽然是无状态协议,但为了实现指望的保持状态功能, 因而引入了Cookie技术有了Cookie再用HTTP协议通讯,就能够管理状态了

  • 无链接

  无链接的含义是限制每次链接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开链接。采用这种方式能够节省传输时间。

4、请求协议和响应协议

  http协议包含由浏览器发送数据到服务器须要遵循的请求协议服务器发送数据到浏览器须要遵循的请求协议。用于HTTP协议交互的信被为HTTP报文。请求端(客户端)的HTTP报文作请求报文,响应端(服务器端)的作响应报文。HTTP报文自己是由多行数据构成的字文本。

  

一、请求协议

  (1)请求格式

  

  (2)get请求与post请求区别

  • GET提交的数据会放在URL以后,以?分割URL和传输数据,参数之间以&相连,如EditBook?name=test1&id=123456. POST方法是把提交的数据放在HTTP包的请求体中.
  • GET提交的数据大小有限制(由于浏览器对URL的长度有限制),而POST方法提交的数据没有限制.
  • GET与POST请求在服务端获取请求数据方式不一样
  • GET方式提交数据,会带来安全问题,好比一个登陆页面,经过GET方式提交数据时,用户名和密码将出如今URL上,若是页面能够被缓存或者其余人能够访问这台机器,就能够从历史记录得到该用户的帐号和密码.

  代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>hello luffycity!</h1>
    <img src='https://gss0.bdstatic.com/-4o3dSag_xI4khGkpoWK1HF6hhy/baike/w%3D268%3Bg%3D0/sign=16535fed6163f6241c5d3e05bf7f8cc5/fd039245d688d43f63d84526771ed21b0ff43bf5.jpg'>
    <a href="http://www.luffycity.com">click</a>
</body>
</html>
index.html
# -*- coding:utf-8 -*-
__author__ = 'Qiushi Huang'

import socket

sock = socket.socket()
sock.bind(("127.0.0.1",8800))   # 服务器地址和端口
sock.listen(5)


while True:
    print("server waiting.......")
    # conn:客户端套接字对象,addr:
    conn,addr = sock.accept()  # 等待用户链接
    data = conn.recv(1024)
    print("data", data)

    # 读取html文件
    with open("index.html", "r") as f:
        data = f.read()

    # 响应首行(HTTP/1.1 200 OK)、响应体
    # conn.send(b"HTTP/1.1 200 OK\r\n\r\n<h1>hello luffycity!</h1>")   # 通常都是须要两个空格分隔\r\n\r\n

    # 响应首行和html文件读取出来的响应体,统一编码为二进制格式发送给浏览器
    conn.send(("HTTP/1.1 200 OK\r\n\r\n%s" % data).encode('utf-8'))

    conn.close()
    """
    请求首行里有多个请求头,每一个请求头用\r\n进行区分。  直到出现\r\n\r\n时,后面的为请求体。
    
    get请求没有请求体,请求体是给post请求用的。
    
    GET提交的数据会放在URL以后,以?分割URL和传输数据:http://127.0.0.1:8800/yuan?name=yuan&age=22
    b'GET /yuan?name=yuan&age=22 HTTP/1.1\r\nHost: 127.0.0.1:8800\r\nConnection: keep-alive\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9,und;q=0.8\r\n\r\n'
    
    请求体(a=1&b=2)  # 注意只有post请求才有请求体
    
    b'GET / HTTP/1.1\r\nHost: 127.0.0.1:8800\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9,und;q=0.8\r\n\r\n'
    
    url:
    协议://IP:端口(80)/路径?a=1&b=2
    """ 

二、响应协议 

  (1)响应格式

  响应协议是服务器给浏览器发的字符串,响应报文的组成:
  响应首行:HTTP/1.1 200 OK 分别是:协议版本、状态码、状态码的缘由短语
  响应头:服务器解释给浏览器的行为
  响应体:浏览器拿到后要渲染的内容,前面也须要\r\n\r\n换行,与响应头区分

 

  

  (2)响应状态码

  状态码的值是当客户端向服务器端发送请求时, 返回的请求结果。借助状态码,用户能够知道服务器端是正常处理了请求,仍是出现了问题。

  状态码如200 OK,以3位数字组成。数字中的一位指定了响应级别,响应级别有如下5种。

  

  代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="http://127.0.0.1:8800"  method="post">
        用户名 <input type="text" name="user">
        密码 <input type="password" name="pwd">
        <input type="submit">
    </form>
</body>
</html>
login.html
# -*- coding:utf-8 -*-
__author__ = 'Qiushi Huang'

import socket

sock = socket.socket()
sock.bind(("127.0.0.1",8801))   # 服务器地址和端口
sock.listen(5)


while True:
    print("server waiting.......")
    # conn:客户端套接字对象,addr:
    conn,addr = sock.accept()  # 等待用户链接
    data = conn.recv(1024)
    print("data", data)

    # 读取html文件
    # with open("index.html", "r") as f:
    with open("login.html", "rb") as f:
        data = f.read()

    # 请求首行(HTTP/1.1 200 OK)、请求体
    # conn.send(b"HTTP/1.1 200 OK\r\n\r\n<h1>hello luffycity!</h1>")   # 通常都是须要两个空格分隔\r\n\r\n

    # 响应首行和html文件读取出来的相应体,统一编码为二进制格式发送给浏览器
    conn.send(b"HTTP/1.1 200 OK\r\nContent-Type:text/html\r\n\r\n%s" % data)

    conn.close()
    """
    user=xiugeng&pwd=123   # 只有post请求才有请求体数据
    
    b'POST / HTTP/1.1\r\nHost: 127.0.0.1:8800\r\nConnection: keep-alive\r\nContent-Length: 20\r\nCache-Control: max-age=0\r\nOrigin: http://127.0.0.1:8800\r\nUpgrade-Insecure-Requests: 1\r\nContent-Type: application/x-www-form-urlencoded\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nReferer: http://127.0.0.1:8800/\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9,und;q=0.8\r\n\r\nuser=xiugeng&pwd=123'
    """

  总结使用get或post的状况:

  一、通常查询的时候用get请求
  二、通常修改更新的时候用post请求

4、wsgiref模块

  最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,返回。

  若是要动态生成HTML,就须要把上述步骤本身来实现。不过,接受HTTP请求、解析HTTP请求、发送HTTP响应都是苦力活,若是咱们本身来写这些底层代码,还没开始写动态HTML呢,就得花个把月去读HTTP规范。

  正确的作法是底层代码由专门的服务器软件实现,咱们用Python专一于生成HTML文档。由于咱们不但愿接触到TCP链接、HTTP原始请求和响应格式,因此,须要一个统一的接口协议来实现这样的服务器软件,让咱们专心用Python编写Web业务。这个接口就是WSGI:Web Server Gateway Interface。而wsgiref模块就是python基于wsgi协议开发的服务模块。

# -*- coding:utf-8 -*-
__author__ = 'Qiushi Huang'

from wsgiref.simple_server import make_server

def application(environ, start_response):
    # 按着http协议解析数据(字典):environ
    # 按着http协议进行组装数据(函数):start_response
    print(environ)   #'PATH_INFO': '/index'
    print(type(environ))  # <class 'dict'>
    # 当前的请求路径
    path = environ.get("PATH_INFO")
    start_response('200 OK', [])

    if path == "/login":
        with open("login.html", "r") as f:
            data = f.read()
    elif path == "/index":
        with open("index.html", "r") as f:
            data = f.read()
    return [data.encode("utf8")]

    # return [b"<h1>hello web<h1>"]   # wsgi要求return的时候要加上列表

# 封装socket
"""
sock = socket.socket()
sock.bind(("127.0.0.1",8090))   # 服务器地址和端口
sock.listen(5)
"""
httped = make_server('', 8090, application)

# 等待用户连接
"""
conn,addr = sock.accept() 
"""
httped.serve_forever()   # 收到连接调用application函数

  本质上讲,这个文件就能够称为一个web框架。  

5、DIY一个WEB框架

相关文章
相关标签/搜索