Django-开胃菜

第一篇:

一.web应用

web应用是什么css

Web应用程序是一种能够经过Web访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只须要有浏览器便可,不须要再安装其余软件html

应用程序有两种模式C/S、B/S。C/S是客户端/服务器端程序,也就是说这类程序通常独立运行。而B/S就是浏览器端/服务器端应用程序,这类应用程序通常借助IE等浏览器来运行。WEB应用程序通常是B/S模式。Web应用程序首先是“应用程序”,和用标准的程序语言,如C、C++等编写出来的程序没有什么本质上的不一样。然而Web应用程序又有本身独特的地方,就是它是基于Web的,而不是采用传统方法运行的。换句话说,它是典型的浏览器/服务器架构的产物。前端

web程序的优势

  • 网络应用程序不须要任何复杂的“展开”过程,你所须要的只是一个适用的浏览器;
  • 网络应用程序一般耗费不多的用户硬盘空间,或者一点都不耗费;
  • 它们不须要更新,由于全部新的特性都在服务器上执行,从而自动传达到用户端;
  • 网络应用程序和服务器端的网络产品都很容易结合,如email功能和搜索功能;
  • 由于它们在网络浏览器窗口中运行,因此大多数状况下它们是经过跨平台使用的 (例如Windows,Mac,Linux等等)

web程序的缺点

  • 网络应用程序强调浏览器的适用性。若是浏览器方没有提供特定的功能,或者弃用特定的平台或操做系统版本(致使不适用),就会影响大量用户;
  • 网络应用依靠互联网远程服务器端的应用文件。所以,当链接出问题时,应用将不能正常使用。
  • 许多网络应用程序不是开源的,只能依赖第三方提供的服务,所以不能针对用户定制化、个性化,并且大多数状况下用户不能离线使用,于是损失了不少灵活性;
  • 它们彻底依赖应用服务商的可及性。若是公司倒闭,服务器中止使用,用户也没法追索之前的资料。对比而看,即便软件制造商倒闭了,传统的安装软件也能够继续运行,尽管不能再更新或有其余用户服务;
  • 类似地,提供方公司对软件和其功能有了更大的控制权。只要他们愿意就能为软件添加新特性,即便用户想等bugs先被解决再更新。跳过较差的软件版本也不可能了。公司能够强加不受欢迎的特性给用户,也能够随意减小带宽来削减开支。
  • 公司理论上能够检索任何的用户行为。这有可能引发隐私安全问题。

B/S架构优势

浏览器/服务器架构(Browser/Server,简称B/S)可以很好地应用在广域网上,成为愈来愈多的企业的选择。浏览器/服务器架构相对于其余几种应用程序体系结构,有以下3方面的优势:python

  • 这种架构采用Internet上标准的通讯协议(一般是TCP/IP协议)做为客户机同服务器通讯的协议。这样可使位于Internet任意位置的人都可以正常访问服务器。对于服务器来讲,经过相应的Web服务和数据库服务能够对数据进行处理。对外采用标准的通讯协议,以便共享数据。
  • 在服务器上对数据进行处理,就处理的结果生成网页,以方便客户端直接下载。
  • 在客户机上对数据的处理被进一步简化,将浏览器做为客户端的应用程序,以实现对数据的显示。再也不须要为客户端单独编写和安装其余类型的应用程序。这样,在客户端只须要安装一套内置浏览器的操做系统,直接安装一套浏览器,就能够实现服务器上数据的访问。而浏览器是计算机的标准设备

总结一下,本质上:浏览器是一个socket客户端,服务器是一个socket服务端mysql

二 基于SOCKET写一个web应用

import socket

def server_run():
    soc = socket.socket()
    soc.bind(('127.0.0.1', 8008))
    soc.listen(5)
    while True:
        conn, addr = soc.accept()
        recv_data = conn.recv(1024)
        print(recv_data)
        # 1 直接在send里写,发送给客户端
        # conn.send(b'HTTP/1.1 200 OK\r\n\r\n<h1>hello web</h1><img src="https://gss2.bdstatic.com/9fo3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike92%2C5%2C5%2C92%2C30/sign=5e3814acf9edab64607f4592965fc4a6/14ce36d3d539b600c0c465d0eb50352ac65cb74b.jpg"></img>')
        #2 打开一个html文件,发送给客户端
        # with open('index.html','r',encoding='utf-8') as f:
        #     data=f.read()
        # conn.send(('HTTP/1.1 200 OK\r\n\r\n%s'%data).encode('utf-8'))
        # 3 动态网页,字符串替换
        import time
        now=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        print(now)
        with open('index.html','r',encoding='utf-8') as f:
            data=f.read()
        data=data.replace('@@@',now)
        conn.send(('HTTP/1.1 200 OK\r\n\r\n%s'%data).encode('utf-8'))
        conn.close()

if __name__ == '__main__':
    server_run()

index文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h2>@@@</h2>

<img src="https://gss2.bdstatic.com/9fo3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike92%2C5%2C5%2C92%2C30/sign=5e3814acf9edab64607f4592965fc4a6/14ce36d3d539b600c0c465d0eb50352ac65cb74b.jpg" alt="">
</body>
</html>

三.手撸web框架

import socket


"""
请求首行
b'GET / HTTP/1.1\r\n
请求头(一大堆kv键值对)
Host: 127.0.0.1:8080\r\n
Connection: keep-alive\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8\r\n
\r\n
请求体
'
"""
server = socket.socket()  # 不传参数默认就是TCP协议
server.bind(('127.0.0.1',8080))
server.listen(5)


while True:
    print('-------------')
    conn, addr = server.accept()  # 阻塞 等待客户端连接
    data = conn.recv(1024)
    # print(data)
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
    # print(data)
    # 手动处理http数据获取用户访问的路径
    # print(data.decode('utf-8').split('\r\n')[0])
    # print(data.decode('utf-8').split('\r\n')[0].split(' ')[1])
    current_path = data.decode('utf-8').split('\r\n')[0].split(' ')[1]
    if current_path == '/index':
        # 路由匹配上以后返回index
        # conn.send(b'<h1>index</h1>')
        with open('index.html','rb') as f:
            conn.send(f.read())
    else:
        # 当匹配不上的时候统一返回404
        conn.send(b'404')
    conn.close()

对于真实开发中的python web程序来讲,通常会分为两部分:服务器程序和应用程序。jquery

服务器程序负责对socket服务器进行封装,并在请求到来时,对请求的各类数据进行整理。web

应用程序则负责具体的逻辑处理。为了方便应用程序的开发,就出现了众多的Web框架,例如:Django、Flask、web.py 等。不一样的框架有不一样的开发方式,可是不管如何,开发出的应用程序都要和服务器程序配合,才能为用户提供服务。sql

这样,服务器程序就须要为不一样的框架提供不一样的支持。这样混乱的局面不管对于服务器仍是框架,都是很差的。对服务器来讲,须要支持各类不一样框架,对框架来讲,只有支持它的服务器才能被开发出的应用使用。数据库

这时候,标准化就变得尤其重要。咱们能够设立一个标准,只要服务器程序支持这个标准,框架也支持这个标准,那么他们就能够配合使用。一旦标准肯定,双方各自实现。这样,服务器能够支持更多支持标准的框架,框架也可使用更多支持标准的服务器。bootstrap

WSGI(Web Server Gateway Interface)就是一种规范,它定义了使用Python编写的web应用程序与web服务器程序之间的接口格式,实现web应用程序与web服务器程序间的解耦。

经常使用的WSGI服务器有uwsgi、Gunicorn。而Python标准库提供的独立WSGI服务器叫wsgiref,Django开发环境用的就是这个模块来作服务器。

咱们利用wsgiref模块来替换咱们本身写的web框架的socket server部分:

def run_server(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ])  # 设置HTTP响应的状态码和头信息
    url = environ['PATH_INFO']  # 取到用户输入的url
    func = None
    for i in list1:
        if i[0] == url:
            func = i[1]
            break
    if func:
        response = func(url)
    else:
        response = b"404 not found!"
    return [response, ]


if __name__ == '__main__':
    httpd = make_server('127.0.0.1', 8090, run_server)
    print("我在8090等你哦...")
    httpd.serve_forever()

urls文件

from views import *

urls = [
    ('/index',index),
    ('/login',login),
    ('/reg',reg),
    ('/get_time',get_time),
    ('/get_user',get_user),
    ('/get_db',get_db),
]

views文件

import time
from jinja2 import Template
import pymysql


def index(env):
    return 'index'

def login(env):
    return 'login'

def reg(env):
    return 'reg'

def get_time(env):
    # 先获取当前时间
    current_time = time.strftime('%Y-%m-%d %X')
    # 打开html文件读取内容返回给客户端
    with open(r'templates/get_time.html','r',encoding='utf-8') as f:
        data = f.read()
    # 由于是以r模式打开的文件,全部获取到的内容就是一堆字符串
    res = data.replace('@@time@@',current_time)  # 字符串的替换
    return res

def get_user(env):

    with open(r'templates/get_user.html','r',encoding='utf-8') as f:
        data = f.read()
    tmp = Template(data)
    # 将字典传递给前端页面 前端经过变量名user_dic就能够获取到该字典
    return tmp.render(user_dic={'name':"jason",'password':'123'})


def get_db(env):
    # 链接数据库 获取数据 渲染到前端页面
    conn = pymysql.connect(
        host = '127.0.0.1',
        port = 3306,
        user = 'root',
        password = '123',
        database = 'day54',
        charset = 'utf8',
        autocommit = True
    )
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    cursor.execute('select * from userinfo')
    user_dict= cursor.fetchall()  # [{},{},{},{}]
    with open(r'templates/get_db.html','r',encoding='utf-8') as f:
        data = f.read()
    tmp = Template(data)
    return tmp.render(user_dict=user_dict)

def error(env):
    return '404 error'

templates里面的html文件

get_db.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <table class="table table-hover table-striped table-bordered">
                <thead>
                    <tr>
                        <th>id</th>
                        <th>name</th>
                        <th>password</th>
                    </tr>
                </thead>
                <tbody>
                    {% for user in user_dict %}  <!--[{},{},{},{}]-->
                        <tr>
                            <td>{{ user.id }}</td>
                            <td>{{ user.name }}</td>
                            <td>{{ user.password }}</td>
                        </tr>
                    {% endfor %}
                </tbody>
            </table>


        </div>
    </div>
</div>
{{ user_dict }}  <!--[{},{},{},{}]-->

</body>
</html>

get_time.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
@@time@@
</body>
</html>

get_user.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<p>{{ user_dic }}</p>
<p>{{ user_dic.name }}</p>
<p>{{ user_dic['password'] }}</p>
<p>{{ user_dic.get('name') }}</p>



</body>
</html>

第二篇 HTTP协议详解

一.协议简介

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

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

二 http协议特性

(1)基于TCP/IP协议之上的应用层协议

(2)基于请求-响应模式

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

(3)无状态保存

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

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

4)无链接

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

请求协议

请求格式:

请求方式: get与post请求

  • GET提交的数据会放在URL以后,以?分割URL和传输数据,参数之间以&相连,如EditBook?name=test1&id=123456. POST方法是把提交的数据放在HTTP包的请求体中.

  • GET提交的数据大小有限制(由于浏览器对URL的长度有限制),而POST方法提交的数据没有限制.

  • GET与POST请求在服务端获取请求数据方式不一样。

    '''
        GET请求
        # 请求首行
        GET / HTTP/1.1\r\n
        # get请求后面的参数
        GET /?name=lqz&age=18 HTTP/1.1\r\n
        # 请求头
        Host: 127.0.0.1:8008\r\n
        Connection: keep-alive\r\n
        Cache-Control: max-age=0\r\n
        Upgrade-Insecure-Requests: 1\r\n
        User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36\r\n
        Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Encoding: gzip, deflate, br\r\n
        Accept-Language: zh-CN,zh;q=0.9\r\n
        Cookie: csrftoken=7xx6BxQDJ6KB0PM7qS8uTA892ACtooNbnnF4LDwlYk1Y7S7nTS81FBqwruizHsxF\r\n\r\n'
        # 请求体(get请求,请求体为空)    
        '''
        '''
        POST请求
        # 请求首行
        POST /?name=lqz&age=18 HTTP/1.1\r\n
        # 请求头
        Host: 127.0.0.1:8008\r\nConnection: keep-alive\r\nContent-Length: 21\r\nCache-Control: max-age=0\r\nOrigin: http://127.0.0.1:8008\r\nUpgrade-Insecure-Requests: 1\r\nContent-Type: application/x-www-form-urlencoded\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 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:8008/?name=lqz&age=18\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\nCookie: csrftoken=7xx6BxQDJ6KB0PM7qS8uTA892ACtooNbnnF4LDwlYk1Y7S7nTS81FBqwruizHsxF\r\n\r\n
        # 请求体
        name=lqz&password=123'
    
        '''
    
    GET请求和POST请求

    ### 响应协议

    响应格式

响应状态码

状态码的职 是当客户端向服务器端发送请求时, 返回的请求 结果。借助状态码,用户能够知道服务器端是正常 理了请求,仍是出 现了 。状态码如200 OK,以3位数字和缘由 成。数字中的 一位指定了响应 别,后两位无分 。响应 别有以5种。

URL简介

统一资源定位符是对能够从互联网上获得的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每一个文件都有一个惟一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它

格式:

  协议://IP:端口(80)/路径?name=lqz&age=18

?以前的是请求路径,?以后的是请求数据部分

import socket


sock=socket.socket()
sock.bind(("127.0.0.1",8808))
sock.listen(5)

while 1:
    print("server waiting.....")
    conn,addr=sock.accept()
    data=conn.recv(1024)
    print("data", data)

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

    conn.send((b"HTTP/1.1 200 OK\r\nContent-type:text/html\r\n\r\n%s"%data))
    conn.close()

借鉴https://www.cnblogs.com/liuqingzheng/articles/9523086.html#_label0https://www.cnblogs.com/Dominic-Ji/articles/10982272.html

相关文章
相关标签/搜索