13

我喜欢使用 Python 的 SimpleHTTPServer 来本地开发各种需要通过 Ajax 调用等加载资源的 Web 应用程序。

当我在我的 URL 中使用查询字符串时,服务器总是重定向到同一个 URL 并附加一个斜杠。

例如/folder/?id=1重定向到/folder/?id=1/使用 HTTP 301 响应。

我只是使用python -m SimpleHTTPServer.

知道如何摆脱重定向行为吗?这是 Python 2.7.2。

4

3 回答 3

5

正确的方法是确保查询参数保持原样,确保您直接对文件名发出请求,而不是让SimpleHTTPServer重定向到您的index.html

例如http://localhost:8000/?param1=1,执行重定向(301)并更改http://localhost:8000/?param=1/与查询参数混淆的 url。

但是http://localhost:8000/index.html?param1=1(使索引文件显式)正确加载。

因此,不让SimpleHTTPServer进行 url 重定向就可以解决问题。

于 2014-09-11T11:43:37.923 回答
3

好的。在 Morten 的帮助下,我想出了这个,这似乎就是我所需要的:只需忽略查询字符串(如果它们存在)并提供静态文件。

import SimpleHTTPServer
import SocketServer

PORT = 8000


class CustomHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):

    def __init__(self, req, client_addr, server):
        SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, req, client_addr, server)

    def do_GET(self):
        # cut off a query string
        if '?' in self.path:
            self.path = self.path.split('?')[0]
        SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)


class MyTCPServer(SocketServer.ThreadingTCPServer):
    allow_reuse_address = True

if __name__ == '__main__':
    httpd = MyTCPServer(('localhost', PORT), CustomHandler)
    httpd.allow_reuse_address = True
    print "Serving at port", PORT
    httpd.serve_forever()
于 2012-10-19T15:22:02.677 回答
2

我不确定重定向是如何生成的......我尝试实现一个非常基本的 SimpleHTTPServer,并且在使用查询字符串参数时我没有得到任何重定向。

在处理请求之前做一些类似self.path.split("/")的事情并处理路径?这段代码可以满足我的想法:

import SocketServer
import SimpleHTTPServer
import os


class CustomHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    def folder(self):
        fid = self.uri[-1].split("?id=")[-1].rstrip()
        return "FOLDER ID: %s" % fid

    def get_static_content(self):
        # set default root to cwd
        root = os.getcwd()
        # look up routes and set root directory accordingly
        for pattern, rootdir in ROUTES:
            if path.startswith(pattern):
                # found match!
                path = path[len(pattern):]  # consume path up to pattern len
                root = rootdir
                break
        # normalize path and prepend root directory
        path = path.split('?',1)[0]
        path = path.split('#',1)[0]
        path = posixpath.normpath(urllib.unquote(path))
        words = path.split('/')
        words = filter(None, words)
        path = root
        for word in words:
            drive, word = os.path.splitdrive(word)
            head, word = os.path.split(word)
            if word in (os.curdir, os.pardir):
                continue
            path = os.path.join(path, word)
            return path

    def do_GET(self):
        path = self.path
        self.uri = path.split("/")[1:]

        actions = {
            "folder": self.folder,
        }
        resource = self.uri[0]
        if not resource:
            return self.get_static_content()
        action = actions.get(resource)
        if action:
            print "action from looking up '%s' is:" % resource, action
            return self.wfile.write(action())
        SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)


class MyTCPServer(SocketServer.ThreadingTCPServer):
    allow_reuse_address = True

httpd = MyTCPServer(('localhost', 8080), CustomHandler)
httpd.allow_reuse_address = True
print "serving at port", 8080
httpd.serve_forever()

试试看:

HTTP GET /folder/?id=500x->"FOLDER ID: 500x"

编辑:

好吧,如果你以前没有使用过 SimpleHTTPServer 的东西,你基本上实现了基本请求处理程序,实现 do_GET()、do_PUT()、do_POST() 等。

然后我通常做的是解析请求字符串(使用re),模式匹配,看看我是否能找到一个请求处理程序,如果没有,如果可能的话,将请求作为对静态内容的请求处理。

你说如果可能的话你想提供静态内容,那么你应该翻转这个模式匹配,首先看看请求是否匹配文件存储,如果不匹配,然后匹配处理程序:)

于 2012-10-18T12:19:27.067 回答