Python 简单HTTP服务器
有没有办法让Python的SimpleHTTPServer支持mod_rewrite?
我正在用Ember.js做一些事情,利用历史API作为位置API。为了让它正常工作,我需要:
1) add some vhosts config in WAMP (not simple), or
2) run python -m simpleHTTPServer (very simple)
所以当我在浏览器中打开localhost:3000
并点击导航(比如关于和用户)时,一切都运行得很好。Ember.js把网址改成了localhost:3000/about
和localhost:3000/users
。
但是当我直接在新标签页中打开localhost:3000/about
时,Python的网络服务器直接返回404错误。
我有一个.htaccess文件,把所有请求重定向到index.html,但我怀疑Python的简单网络服务器并不真的读取这个htaccess文件(我这样想对吗?)
我尝试下载了PHP 5.4.12并运行内置的网络服务器,网址和htaccess的mod_rewrite都能正常工作。但我还是不太想从稳定的5.3升级到(可能还不够稳定的)5.4.12,所以如果有办法让Python的简单网络服务器支持mod_rewrite,那就太好了。
谢谢你的回答。
4 个回答
如果你知道哪些情况需要重定向,你可以创建一个新的类来继承SimpleHTTPRequestHandler,然后进行重定向。这样的话,任何请求缺失的文件都会被重定向到/index.html。
import SimpleHTTPServer, SocketServer
import urlparse, os
PORT = 3000
class MyHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_GET(self):
# Parse query data to find out what was requested
parsedParams = urlparse.urlparse(self.path)
# See if the file requested exists
if os.access('.' + os.sep + parsedParams.path, os.R_OK):
# File exists, serve it up
SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self);
else:
# redirect to index.html
self.send_response(302)
self.send_header('Content-Type', 'text/html')
self.send_header('location', '/index.html')
self.end_headers()
Handler = MyHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)
print "serving at port", PORT
httpd.serve_forever()
SimpleHTTPServer 是一个简单的服务器,它不支持 Apache 服务器的一些功能,比如 .htaccess 文件,也就是说它不会按照这些文件里的设置来运行,因为它根本就不是 Apache 服务器。同时,它也不能处理 PHP 代码。
我根据pd40的回答做了一些修改,得到了这个方法,它不会进行重定向,而是会传统地“发送index.html文件,而不是404错误页面”。这个方法并没有经过优化,但在测试和开发时完全可以用,这正是我所需要的。
import SimpleHTTPServer, SocketServer
import urlparse, os
PORT = 3456
class MyHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_GET(self):
# Parse query data to find out what was requested
parsedParams = urlparse.urlparse(self.path)
# See if the file requested exists
if os.access('.' + os.sep + parsedParams.path, os.R_OK):
# File exists, serve it up
SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self);
else:
# send index.hmtl
self.send_response(200)
self.send_header('Content-Type', 'text/html')
self.end_headers()
with open('index.html', 'r') as fin:
self.copyfile(fin, self.wfile)
Handler = MyHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)
print "serving at port", PORT
httpd.serve_forever()