【问题标题】:html in do_GET() method of a simple Python webserver简单 Python 网络服务器的 do_GET() 方法中的 html
【发布时间】:2023-03-05 11:18:01
【问题描述】:

我对 Python 比较陌生,但最近用它做了很多不同的事情,我非常喜欢它。但是,我遇到了以下代码的麻烦/阻塞。

import http.server
import socketserver
import glob
import random
class Server(http.server.SimpleHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200, 'OK')
        self.send_header('Content-type', 'html')
        self.end_headers()
        self.wfile.write(bytes("<html> <head><title> Hello World </title> </head> <body>", 'UTF-8'))
        images = glob.glob('*.jpg')
        rand = random.randint(0,len(images)-1)
        imagestring = "<img src = \"" + images[rand] + "\" height = 1028 width = 786 align = \"right\"/> </body> </html>"
        self.wfile.write(bytes(imagestring, 'UTF-8'))

    def serve_forever(port):
        socketserver.TCPServer(('', port), Server).serve_forever()
if __name__ == "__main__":
    Server.serve_forever(8000)

我在这里尝试做的是从目录中的多个图像中获取随机图像并将其添加到对 Web 请求的响应中。 代码工作正常,但是当我通过浏览器访问服务器时,图像不显示。页面的 html 与预期的一样。文件的权限是 755。我还尝试在 do_GET 方法中创建一个 index.html 文件。那也没用。我的意思是 index.html 生成的很好,但是这次浏览器中的响应没有显示任何内容(甚至没有显示标题中的 hello world)。

我在这里遗漏了什么非常简单的东西吗?我在想我是否应该重载底层 SocketServer.BaseServer 的 handle_request,因为文档说你永远不应该重写 BaseHTTPServer 的 handle() 方法,而应该重写相应的 do_* 方法?

【问题讨论】:

    标签: python html webserver image


    【解决方案1】:

    我把代码改成:

    #!usr/bin/python3.2
    import http.server
    import socketserver
    import glob
    import random
    import sys
    
    class Server(http.server.SimpleHTTPRequestHandler):
    def do_GET(self):
        referer = self.headers.get('Referer')
        print("The referer is", referer)
        if referer == None:
            self.protocol_version='HTTP/1.1'
            self.send_response(200, 'OK')
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            self.wfile.write(bytes("<html> <head><title> Hello World </title> </head> <body>", 'UTF-8'))
            images = glob.glob('*.jpg')
            rand = random.randint(0,len(images)-1)
            filepath = images[rand]
            imagestring = "<img src = \"" + images[rand] + "\" height = 1028 width = 786 align = \"right\"/> </body> </html>"
            self.wfile.write(bytes(imagestring, 'UTF-8'))
        else:
            imgname = self.path
            print ("Image requested is: ", imgname[1:])
            imgfile = open(imgname[1:], 'rb').read()
            self.send_header('Content-type', 'image/jpeg')
            self.send_header('Content-length', sys.getsizeof(imgfile))
            self.end_headers()
            self.wfile.write(imgfile)
    
    def serve_forever(port):
        socketserver.TCPServer(('', port), Server).serve_forever()
    
    if __name__ == "__main__":
        Server.serve_forever(8000)
    

    使用 tcpflow,我可以看到图像作为二进制数据通过网络发送,但我仍然在浏览器中看不到图像。

    【讨论】:

    • 这不是您问题的答案。您应该编辑您的问题以包含此信息。
    【解决方案2】:

    哦,你在这一行中混合了很多 "\"

    "&lt;img src = \" + images[rand] + '\" height = 1028 width = 786 align = \"right\"/&gt; &lt;/body&gt; &lt;/html&gt;'

    应该是这样的:

    '<img src = "' + images[rand] + '" height = 1028 width = 786 align="right"/> </body> </html>'
    

    否则你将不会得到图像而是文本"images[rand]"

    【讨论】:

    • 对不起。实际代码中为:imagestring = "
    【解决方案3】:

    我怀疑当浏览器向您的服务器发送对您放入 html 的图像的请求时,您正在向他们发送另一个页面的 html。您可能需要在 do_GET 的开头添加一个检查,以确保它不是对图像的请求(或者是对某些特定页面的请求)。

    【讨论】:

    • 就图像而言,我认为服务器在相同或不同的 TCP 连接中将图像作为二进制数据发送(取决于您使用的是持久性还是非持久性 HTTP)。在任何一种情况下,图像都会包裹在通常的 HTTP 标头周围。但我明白你的意思,它仍然需要发送图像文件。如果您在终端中看到服务器响应,您可以看到它以 200 响应图像文件请求。
    • 当您 wget/curl 从您的脚本(即您在浏览器中导航到的那个)提供的图像的 URL 时会发生什么?生成的文件是作为图像可见,还是在文本编辑器中打开时看起来像 HTML?
    • 使用 wget/curl 它只会发送纯 html。使用 tcpflow 并读入环回接口上传递的消息的进一步调查,我发现服务器实际上并没有发送图像(作为二进制数据)。我看到的是浏览器对图像的第二次请求。现在,我可以将传入的请求作为对其中一张图像的请求进行检查,但问题是如何实际在线发送图像?事实证明 http.server 没有任何编码方法。进一步阅读指向我使用 httplib。
    【解决方案4】:

    我有一些与您修改后的版本(作为答案发布的版本)非常相似的代码,这些代码对我有用。唯一的区别是我不发送内容长度,所以这可能是你的问题的原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-14
      • 2010-10-21
      • 2011-12-24
      • 2015-10-24
      • 2022-12-22
      • 1970-01-01
      • 2016-05-18
      相关资源
      最近更新 更多