16577


jsからlocalhostで動いているpythonにリクエストを送ってます。

jsではget引数にmain.py?url={jsでencodeURIComponentしたURL}という形でリクエストしています。

受け取り側では

[code]

    form = cgi.FieldStorage()
    form['url'].value
    
[/code]

という形で取得しています。

jsでencodeURIComponentする前のURLが「<http://example.com/>」のような場合には問題なく取得できるのですが「<http://example.com/?hoge=fuga>」のようにこちらにもget引数がついていると、その部分がcgi.FieldStorage()で取得されてしまい、逆に'url'というキーの値がない、という状態になっています。

こういう場合、pythonではどのように受け取るべきなのでしょうか。

ちなみに、リクエストしているURLを直接ブラウザで叩いても同じ状態になります。


CC BY-SA 3.0
2015-07-02T07:54:23.610
11954
2015-09-13T20:52:17.667
2015-07-02T08:01:38.037
10373
10373
question
python
pythonでget引数にjavascriptでencodeURIComponent()したurlを渡したらcgi.FieldStrage()がおかしくなる


僕がテストする限りとくに問題なく動きました。ブラウザのJavaScriptコンソールで`encodeURIComponent('http://example.com/?hoge=fuga')`とすると`http%3A%2F%2Fexample.com%2F%3Fhoge%3Dfuga`が得られます。

テストプログラム test.py

[code]

    #!/usr/bin/env python
    import cgi
    form = cgi.FieldStorage()
    print 'Content-Type: text/html'
    print
    print form['url'].value
    
[/code]

端末で

[code]

    mkdir cgi-bin
    # 上のtest.pyをcgi-binの下に保存して実行属性をつける
    chmod 755 cgi-bin/test.py
    
    # CGIサーバ起動
    python -m CGIHTTPServer
    
[/code]

ブラウザで`http://localhost:8000/cgi-
bin/test.py?url=http%3A%2F%2Fexample.com%2F%3Fhoge%3Dfuga`をアクセス

ソースを確認すると`http://example.com/?hoge=fuga`が正しく得られました。


CC BY-SA 3.0
2015-07-15T02:05:02.900
12364
2015-07-15T02:05:02.900
7837
11954
answer


動作確認にPythonの標準ライブラリのサーバを使っている事と思いますが、そのサーバの問題です。手元でも`python3 -m http.server
--cgi`で起動したサーバで再現しました。CGIはそのままで、他のサーバでは動くはずです。

`cgi.FieldStorage()`はサーバが用意した環境変数`QUERY_STRING`を使用すると思うのですが、標準ライブラリのサーバはこれが大雑把で、urlを`rfind('?')`で分割して使っているようです。

`http://localhost:8000/cgi-bin/cgi-try.py?url=http://example.com/?hoge=fuga`
という url
だと、通常のサーバから渡される`QUERY_STRING`は`url=http://example.com/?hoge=fuga`だと思いますが
Python のサーバでは`hoge=fuga`になってしまいます。

(こういう物なのか、バグと考えるべきなのか分かりません)


CC BY-SA 3.0
2015-09-13T20:52:17.667
16577
2015-09-13T20:52:17.667
3054
11954
answer