我喜欢使用 Python 的 SimpleHTTPServer 来本地开发各种需要通过 Ajax 调用等加载资源的 Web 应用程序。
当我在我的 URL 中使用查询字符串时,服务器总是重定向到同一个 URL 并附加一个斜杠。
例如/folder/?id=1
重定向到/folder/?id=1/
使用 HTTP 301 响应。
我只是使用python -m SimpleHTTPServer
.
知道如何摆脱重定向行为吗?这是 Python 2.7.2。
我喜欢使用 Python 的 SimpleHTTPServer 来本地开发各种需要通过 Ajax 调用等加载资源的 Web 应用程序。
当我在我的 URL 中使用查询字符串时,服务器总是重定向到同一个 URL 并附加一个斜杠。
例如/folder/?id=1
重定向到/folder/?id=1/
使用 HTTP 301 响应。
我只是使用python -m SimpleHTTPServer
.
知道如何摆脱重定向行为吗?这是 Python 2.7.2。
正确的方法是确保查询参数保持原样,确保您直接对文件名发出请求,而不是让SimpleHTTPServer
重定向到您的index.html
例如http://localhost:8000/?param1=1
,执行重定向(301)并更改http://localhost:8000/?param=1/
与查询参数混淆的 url。
但是http://localhost:8000/index.html?param1=1
(使索引文件显式)正确加载。
因此,不让SimpleHTTPServer
进行 url 重定向就可以解决问题。
好的。在 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()
我不确定重定向是如何生成的......我尝试实现一个非常基本的 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),模式匹配,看看我是否能找到一个请求处理程序,如果没有,如果可能的话,将请求作为对静态内容的请求处理。
你说如果可能的话你想提供静态内容,那么你应该翻转这个模式匹配,首先看看请求是否匹配文件存储,如果不匹配,然后匹配处理程序:)