13

私は、Ajax 呼び出しなどを介してリソースをロードする必要があるあらゆる種類の Web アプリケーションのローカル開発に、Python の SimpleHTTPServer を使用するのが好きです。

URL でクエリ文字列を使用すると、サーバーは常にスラッシュが追加された同じ URL にリダイレクトします。

たとえば、HTTP 301 応答を使用するよう/folder/?id=1にリダイレクトします。/folder/?id=1/

を使用してサーバーを起動するだけpython -m SimpleHTTPServerです。

リダイレクト動作を取り除く方法はありますか? これは Python 2.7.2 です。

4

3 に答える 3

5

これを行う正しい方法は、クエリ パラメータが本来あるべき状態のままであることを確認することですSimpleHTTPServerindex.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 に答える