📜  使用Python的SimpleHTTPServer模块提供文件

📅  最后修改于: 2020-08-28 05:48:23             🧑  作者: Mango

介绍

服务器是用于处理请求并通过网络将数据传递到客户端的计算机软件或硬件。存在各种类型的服务器,最常见的服务器是Web服务器,数据库服务器,应用程序服务器和事务服务器。

在测试简单项目时,诸如ApacheMonkeyJigsaw之类的广泛使用的Web服务器的建立非常耗时,并且开发人员的重点已从产生应用程序逻辑转移到设置服务器。

Python的SimpleHTTPServer模块是一个有用且直接的工具,开发人员可以在许多用例中使用它,主要的是它是一种从目录提供文件的快速方法。

它消除了与安装和实施可用的跨平台Web服务器相关的繁琐过程。

注意:虽然这SimpleHTTPServer是从目录轻松提供文件的一种好方法,但不应在生产环境中使用它。根据官方的Python文档,它“仅实现基本的安全检查”。

什么是HTTP服务器

HTTP代表超文本传输​​协议。让我们把协议看作是英语这样的口语。英语有一套规则和词汇。因此,如果我们都理解定义英语的规则和词汇,那么我们就可以有效地用英语进行交流。

就像人类一样,电子设备也彼此通信。因此,他们需要一套“规则和词汇”来彼此主动传递和接收信息。

协议是一组标准规则,可促进电子设备之间的成功通信。这些相互接受和实施的规则集包括用于启动数据发送和接收的命令,在设备之间传输的数据类型,如何检测数据中的错误,如何确认成功的数据传输等等。

例如,当您使用浏览器执行简单搜索时,涉及两个基本系统-HTTP ClientHTTP Server

客户端(通常称为浏览器)可以是复杂的程序,例如Google Chrome或Firefox,但也可以像CLI应用程序一样简单。客户端将您的请求发送到服务器,该服务器处理HTTP请求并向客户端提供响应。对于浏览器,响应通常是HTML页面。

Python的SimpleHTTPServer模块

当您需要运行快速的Web服务器时,设置生产级服务器实在是太过分了。

Python的SimpleHTTPServer模块是一种省力的工具,您可以利用它来将系统中的任何目录转换为简单的Web服务器。它附带一个简单的HTTP服务器,该服务器提供标准GETHEAD请求处理程序。

使用内置的HTTP服务器,不需要安装或配置任何东西即可启动和运行Web服务器。

注意:Python SimpleHTTPServer模块已合并到http.serverPython 3中的模块中。在本文中,我们将一直使用Python 3版本,但是如果您使用的是Python 2,则可以换http.serverSimpleHTTPServer它,并且在大多数情况下应该可以使用。

命令行用法

启动提供运行命令的目录的Web服务器的最简单方法是,使用终端简单地导航到项目的目录并运行:

Python 2 

$ python -m SimpleHTTPServer 8000

Python 3 

$ python3 -m http.server 8000

通过运行此命令,您将能够通过浏览器访问目录中的文件localhost:8000

如您所见,服务器提供了一个简单的目录UI,您可以在其中访问任何文件。这是通过HTTP直接在本地提供文件的最简单方法。

默认Python使用

由于某种原因,通过命令行运行此服务器可能不适合我们的用例。在这种情况下,我们可以改为使用SimpleHTTPRequestHandler对象直接在代码中使用服务器。但是首先,我们需要使用套接字服务器进行设置。

HTTP协议之下的是UDP(用户数据报协议)或TCP(传输控制协议),它们是处理从一个网络位置到另一个网络位置的数据传输的传输协议。由于我们正在运行HTTP服务器,因此我们的应用程序将通过包含IP地址和端口号的TCP套接字地址来使用TCP协议。可以使用socketserver.TCPServer以下实现的Python进行设置:

import http.server
import socketserver

PORT = 8000

handler = http.server.SimpleHTTPRequestHandler

with socketserver.TCPServer(("", PORT), handler) as httpd:
    print("Server started at localhost:" + str(PORT))
    httpd.serve_forever()

注意AttributeError: __exit__对于版本<3.6的Python版本,代码将因错误而失败。这是因为在以前的版本socketserver.TCPServer中,不支持与上下文管理器(with关键字)一起使用。在这种情况下,您需要致电server_close()以停止服务器。

默认情况下,SimpleHTTPRequestHandlerservs文件来自当前目录和相关子目录。顾名思义,它是一个简单的HTTP请求处理程序。作为它的简单服务器,它仅允许您检索数据而不将其发布到服务器。因此,它仅通过和实现HTTP GETHEAD方法。do_GET()do_HEAD()

传递给的参数TCPServer代表IP地址和端口号。通过将IP地址保留为空,服务器将侦听所有可用的IP地址,而我们将端口设置为8000。这意味着它将可以在上访问localhost:8000

最后,httpd.server_forever()启动服务器,侦听并响应来自客户端的传入请求。

只需执行以下文件即可启动服务器: 

$ python3 simple-server.py

就像命令行用法一样,我们现在可以通过Web浏览器访问目录:

自定义路径

我们可以采用的另一种方法是创建一个自定义类,该类SimpleHTTPRequestHandler使用某些自定义功能扩展和处理我们的请求。为此,我们实现了自己的do_GET()功能。

但是在开始之前,假设我们有一个要提供的HTML文件mywebpage.html




  Using Python's SimpleHTTPServer Module
  


  

Rectangle served by SimpleHTTPServer

为了从非路径提供HTML /mywebpage.html,我们可以使用自定义处理程序在所需的任何路径上提供HTML 。在此示例中,我们将其仅用于根路径/

import http.server
import socketserver

class MyHttpRequestHandler(http.server.SimpleHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/':
            self.path = 'mywebpage.html'
        return http.server.SimpleHTTPRequestHandler.do_GET(self)

# Create an object of the above class
handler_object = MyHttpRequestHandler

PORT = 8000
my_server = socketserver.TCPServer(("", PORT), handler_object)

# Star the server
my_server.serve_forever()

同样,运行此脚本将使我们能够通过浏览器访问它:

但是,我们可以通过self引用对响应进行更多的自定义,我们将在下一部分中进行介绍。

返回动态HTML

Web服务器的常见用法是提供动态生成的HTML。尽管这只是非常简单的服务器,但它也可以执行此任务。除了发送动态HTML之外,我们还可以设置不同的状态代码,标题等。在以下示例中,我们设置一些标题并返回使用query参数生成的动态HTML name

import http.server
import socketserver
from urllib.parse import urlparse
from urllib.parse import parse_qs

class MyHttpRequestHandler(http.server.SimpleHTTPRequestHandler):
    def do_GET(self):
        # Sending an '200 OK' response
        self.send_response(200)

        # Setting the header
        self.send_header("Content-type", "text/html")

        # Whenever using 'send_header', you also have to call 'end_headers'
        self.end_headers()

        # Extract query param
        name = 'World'
        query_components = parse_qs(urlparse(self.path).query)
        if 'name' in query_components:
            name = query_components["name"][0]

        # Some custom HTML code, possibly generated by another function
        html = f"

Hello {name}!

" # Writing the HTML contents with UTF-8 self.wfile.write(bytes(html, "utf8")) return # Create an object of the above class handler_object = MyHttpRequestHandler PORT = 8000 my_server = socketserver.TCPServer(("", PORT), handler_object) # Star the server my_server.serve_forever()

并使用URL运行此代码http://localhost:8000?name=Billy将产生:

您为name查询参数设置的任何值都将显示在屏幕上!您甚至可以省略name查询参数,然后看看会发生什么。

如您所见,创建自定义请求处理程序使我们可以通过更改do_GET方法的实现来尽可能多地操作响应,而对于默认实现则无法对响应进行控制。

使用HTTP HEAD方法(通过do_HEAD()函数)可以完成相同的操作,但是由于它与GET方法非常相似,因此我们将其作为练习留给读者。

结论

Python为我们提供了SimpleHTTPServer模块(或http.server在Python 3中),该模块可用于通过HTTP快速轻松地为本地目录中的文件提供服务。它可以用于许多开发或其他内部任务,但不用于生产。

这对于本地使用来说是一个很好的解决方案,因为诸如ApacheMonkeyJigsaw之类的Web服务器更难建立,并且对于开发活动而言往往过于刻板。