1、学习Djiango预备知识

主要内容

一、Djiango介绍
二、http协议介绍
三、网络的七层协议 http协议本质是基于socket实现
四、web服务器的实现
五、总结

Djiango介绍

Django是一个用 Python 编写的 Web 框架。Web 框架是一种软件,基于web框架可以开发动态网站,各种应用程序以及服务。它提供了一系列工具和功能,可以解决许多与Web开发相关的常见问题,比如:安全功能,数据库访问,会话,模板处理,URL路由,国际化,本地化,等等

HTTP协议介绍

1、http协议是指?

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

2、特点

简单快速:客户向服务器请求服务时,只需传送请求方法和路径。
灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记
无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。[与网络层tcp三次握手对应记忆]
无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
支持B/S和C/S模式

3、http协议 之URL

HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。以下面这个URL为例,介绍下普通URL的各部分组成:

http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name
从上面的URL可以看出,一个完整的URL包括以下几部分:

1.协议部分:该URL的协议部分为“http:”,这代表网页使用的是HTTP协议。在Internet中可以使用多种协议,如HTTP,FTP等等本例中使用的是HTTP协议。在"HTTP"后面的“//”为分隔符
2.域名部分:该URL的域名部分为“www.aspxfans.com”。一个URL中,也可以使用IP地址作为域名使用
3.端口部分:跟在域名后面的是端口,域名和端口之间使用“:”作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口
4.虚拟目录部分:从域名后的第一个“/”开始到最后一个“/”为止,是虚拟目录部分。虚拟目录也不是一个URL必须的部分。本例中的虚拟目录是“/news/”
5.文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分。本例中的文件名是“index.asp”。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名
6.锚部分:从“#”开始到最后,都是锚部分。本例中的锚部分是“name”。锚部分也不是一个URL必须的部分
7.参数部分:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。本例中的参数部分为“boardID=5&ID=24618&page=1”。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符
(http协议详情见原文:https://www.cnblogs.com/ranyonsue/p/5984001.html)

4、http协议与tcp/ip关系?

HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)

tcp/ip七层协议

应用层–>表示层–>会话层–>传输层–>网络层–>物理层
http 协议 tcp/udp socket编程


概念
http:浏览器发送请求,服务器进行响应;
socket编程,即客户端和服务器通信;二者原理一致。Http协议可以说是基于Socket的再上层封装。

简单web的实现

0、基于socket编程实现web服务器

import socket
def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('localhost', 8080))
    status = 1
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, status)
    sock.listen(5)
    while True:
        # 等待浏览器的访问
        conn,addr = sock.accept()
        # 接收浏览器发来的请求内容[recv]
        data = conn.recv(1024)
        print(data)
        
        #  给浏览器返回内容[send]
        conn.send(b"HTTP/1.1 200 OK\r\nContent-Type:text/html; charset=utf-8\r\n\r\n")
          #注意编码
        conn.send("how are you? aa".encode('utf-8'))
        # 关闭socket
        conn.close()
if __name__ == '__main__':
    main()

思考

如果是要返回一个图片呢?一个文件呢?【app】这就涉及你自己要负责实现文件的传送了,我们学socket传文件时,遇到过粘包问题,解决起来挺麻烦的,利用现成的东西wsgi

介绍wsgi

WSGI(Web Server Gateway Interface)是一种规范。建立这种规范,程序就不再重复编写web server(socket服务端),而是直接使用现成的实现WSGI的模块(例如:wsgiref、uwsgi、werkzeug),从而让程序员更加专注与业务代码。

1、利用wsgiref 实现一个web服务器

# 基于wsgiref实现web服务器
from wsgiref.simple_server import make_server

def run_server(environ, start_response):
    """
    当用户访问http://127.0.0.1:8000/ 立即执行该函数并将函数的返回值返回给用户浏览器
    :param environ:  请求相关的内容,比如浏览器类型、版本、来源地址、url 等同于socket编程中收到的浏览器信息
    :param start_response:响应相关的内容
    :return:
    """
    start_response('200 OK', [('Content-Type', 'text/html')])
    return [bytes("hahahaha",encoding='utf-8')]
if __name__ == '__main__':
    httpd = make_server('localhost', 8000, run_server)
    httpd.serve_forever()

2、利用wsgiref 实现支持多url的web服务器 [路由系统,输入不同的url查看不同的内容]

 #基于wsgiref实现多路由的web服务器
 #实现路由分发器,将url与对应的函数进行匹配
from wsgiref.simple_server import make_server

def book(environ, start_response):
    print("book page")
    return [bytes('<h2> book page</h2>',encoding='utf-8')]
def cloth(environ, start_response):
    print('cloth page')
    return [bytes('<h2> cloth page</h2>', encoding='utf-8')]
def routers():

   urls_info = {
       '/book': book,
       '/cloth': cloth,
   }
   return urls_info
def run_server(environ, start_response):
    """
    :param environ: 浏览器请求的相关信息 版本、url
    :param start_response: 响应信息
    :return:
    """
    start_response('200 OK', [('Content-Type', 'text/html')])
    url = environ.get('PATH_INFO')
    # print("url:",url)
    urlpatterns = routers()
    if url in urlpatterns:
    	# 接收函数返回的值 
        func_data=urlpatterns[url](environ, start_response)
        # 将接收的值返回给浏览器
        return func_data
   else:
        return [bytes('<h2>not find</h2>',encoding='utf-8')]
if __name__ == '__main__':
    httpd = make_server('localhost', 8000, run_server)
    httpd.serve_forever()

3、利用wsgiref 实现图片显示的服务器

图片显示的原理:每一张图片为单独的一次请求。[没有加载出来]

# 基于wsgiref 实现图片显示服务器
import os
import re
BASE_DIR =   os.path.abspath(__file__)   #当前文件绝对路径
BASE_PATH = os.path.dirname(BASE_DIR)    # 前面的路径
from wsgiref.simple_server import make_server
def book(environ, start_response):
    print("book page")
    start_response('200 OK', [('Content-Type', 'text/html')])
    # 前端路径
    data = """
        <h1>欢迎来到日本专区</h1>
            <img src='/static/imgs/book.jpg'/>
        <p>上路飞学城,看尽天下大片</p>
    """
    return [bytes(data, encoding='utf-8')]
    #return [bytes('<h2> book page</h2>',encoding='utf-8')]
    
def cloth(environ, start_response):
    print('cloth page')
    start_response('200 OK', [('Content-Type', 'text/html')])
    return [bytes('<h2> cloth page</h2>', encoding='utf-8')]
def routers():

   urls_info = {
       '/book': book,
       '/cloth': cloth,
   }
   return urls_info
def img_handler(url):
    """
    :param url: 前端访问的url  /data/imgs/book.jpg
    :return:  找到后台数据的位置(re.sub),然后打开文件,将数据返回给前端
                打开文件时,先判断文件是否存在
    """
    # print("BASE_DIR:", BASE_DIR)
    print("BASE_PATH:", BASE_PATH)
    img_path =re.sub('/static', '/static_data', url)
    # img_path = os.path.join(BASE_DIR,img_path)
    img_abs_path = "%s%s" % (BASE_PATH, img_path)
    #print('img_abs_path:', img_abs_path)
    if os.path.isfile(img_abs_path):
        #print("------file exist-------")
        f = open("img_abs_path ", "rb")
        data = f.read()  #获取图片内容
        return [data, 0]  # 0 表示没有错  1 有错
    else:
        return [None, 1]
    
def run_server(environ, start_response):
    """
    :param environ: 浏览器请求的相关信息 版本、url
    :param start_response: 响应信息
    :return:
    """
    url = environ.get('PATH_INFO')
    print("url:",url)
    urlpatterns = routers()
    if url in urlpatterns:
        func_data=urlpatterns[url](environ, start_response)
        return func_data
    elif url.startswith('/static/'):# 代表图片
        img_data, img_status = img_handler(url)
        if img_status == 0:
            start_response("200 OK", ["Content-Type", 'text/jpeg'])
            return [img_data, ]
    else:
        start_response("404", ['Content-Type', 'text/html'])
        return [bytes('404,not find</h2>',encoding='utf-8')]
if __name__ == '__main__':
    httpd = make_server('localhost', 8000, run_server)
    httpd.serve_forever()

总结

1、浏览器是socket客户端,网站是socket服务器
2、wsgi是一个规范,wsgiref 实现了这个规范 并且 在其内部实现了socket服务端
3、根据不同的url去执行不同的函数,即为路由系统
4、函数 即处理业务逻辑
5、图片、css、js文件统一称为静态文件。需要经过 从前端获取url---->找到后端的位置----->打开文件---->读取文件---->返回给浏览器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值