Почему SimpleHTTPServer перенаправляет на? Querystring/когда я запрашиваю? Querystring?
Мне нравится использовать Python SimpleHTTPServer для локальной разработки всех видов веб-приложений, требующих загрузки ресурсов через вызовы Ajax и т.д.
Когда я использую строки запроса в своих URL-адресах, сервер всегда перенаправляет на тот же URL-адрес с добавлением косой черты.
Например, /folder/?id=1
перенаправляет на /folder/?id=1/
с помощью ответа HTTP 301.
Я просто запускаю сервер, используя python -m SimpleHTTPServer
.
Любая идея, как я могу избавиться от поведения перенаправления? Это Python 2.7.2.
Ответы
Ответ 1
Хорошо. С помощью Мортен я придумал это, что, кажется, все, что мне нужно: просто игнорируйте строки запроса, если они есть и служат статическим файлам.
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()
Ответ 2
Правильный способ сделать это, чтобы гарантировать, что параметры запроса остаются такими, какими они должны были, - убедиться, что вы выполняете запрос к имени файла напрямую, вместо того, чтобы SimpleHTTPServer
перенаправлять на index.html
Например, http://localhost:8000/?param1=1
выполняет перенаправление (301) и изменяет URL-адрес на http://localhost:8000/?param=1/
, который помещается в параметр запроса.
Однако http://localhost:8000/index.html?param1=1
(что делает файл индекса явным) загружается правильно.
Так что просто не позволяя SimpleHTTPServer
выполнять перенаправление URL-адресов, решает проблему.
Ответ 3
Я не уверен, как создается перенаправление... Я попытался реализовать очень простой 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"
EDIT:
Итак, если вы раньше не использовали материал SimpleHTTPServer, вы в основном реализуете обработчик базового запроса, реализуете do_GET(), do_PUT(), do_POST() и т.д.
То, что я обычно делаю тогда, - это проанализировать строку запроса (используя re), совпадение шаблонов и посмотреть, могу ли я найти обработчик запроса, а если нет, обработайте запрос как запрос на статический контент, если это возможно.
Вы говорите, что хотите использовать статический контент, если это вообще возможно, тогда вы должны перевернуть этот шаблон, сопоставляя его, а FIRST посмотреть, соответствует ли запрос файловому хранилищу, а если нет, то сопоставить с обработчиками:)