Rumah >pembangunan bahagian belakang >Tutorial Python >Flask框架返回GET请求的参数为什么会导致500 Internal Server Error?

Flask框架返回GET请求的参数为什么会导致500 Internal Server Error?

WBOY
WBOYasal
2016-06-06 16:24:033406semak imbas

回复内容:

首先明确这几个Python的规则,然后再做推断。

1. data是传入的查询参数,按照现代各类编程语言的玩法,是要先转换成unicode字符串的,这样做国际化和本地化才比较方便。所以data的类型就是unicode,type(data)返回的结果就是unicode。这个unicode是Python的内置类型,同时也是一个函数。

2. type(data)==unicode之后,在Python的控制台直接打印,会获得 "" 这是因为Python控制台在打印时会自动调用对象的 .__str__() 方法,来获得一个可以显示的字符串,这也是Python的方便之处。你可以手工在Python控制台里执行 str(unicode) 会得到 "" 。

3. Web框架是如何工作的?常用的PythonWeb框架在请求处理函数所需的返回值类型是str,这样就可以直接发送给客户端了。如果需要定制响应头,可以用框架内置的Response对象。但无论如何,这些框架的底层基本都是直接实现WSGI接口,一个Python通用的Web服务器接口。而如上的start_response() 其实就是Flask在检测到函数返回值为一个函数时,就把他当成了一个WSGI函数来处理。传入了WSGI函数的两个参数,一个dict类型的环境,一个function类型start_response函数。即实际调用的是unicode(environ,start_response)。

4. unicode函数的用法是将一个字符串转换成unicode对象。第一个参数是字符串,第二个参数是编码字符集。比如
>>> print(unicode('你好','utf-8'))
你好

所以,你的程序所遇到的问题是这样的。data是个unicode类型,也是unicode函数。Flask里作为返回值时,Flask检测到这是个函数,于是当成了一个WSGI application来处理,传入了environ和start_response两个参数。而unicode函数实际接受的两个参数是字符串和字符集,所以遇到了参数错误。

你如果需要在Flask知道data的类型,可以用 str(type(data)) 。这样将输出转换成可显示的字符串,就能看到了。 在 Flask 中,根据 method handle 返回的结果,首先调用 make_response

<code class="language-python3"><span class="k">def</span> <span class="nf">make_response</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">rv</span><span class="p">):</span>
    <span class="o">...</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">rv</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">response_class</span><span class="p">):</span>
        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">rv</span><span class="p">,</span> <span class="p">(</span><span class="n">text_type</span><span class="p">,</span> <span class="nb">bytes</span><span class="p">,</span> <span class="nb">bytearray</span><span class="p">)):</span> 
            <span class="n">rv</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">response_class</span><span class="p">(</span><span class="n">rv</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">status</span><span class="o">=</span><span class="n">status</span><span class="p">)</span>
            <span class="n">headers</span> <span class="o">=</span> <span class="n">status</span> <span class="o">=</span> <span class="k">None</span>
        <span class="c"># rv是 method handle返回的结果,在k神代码中是 <type></type></span>
        <span class="k">else</span><span class="p">:</span> 
            <span class="n">rv</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">response_class</span><span class="o">.</span><span class="n">force_type</span><span class="p">(</span><span class="n">rv</span><span class="p">,</span> <span class="n">request</span><span class="o">.</span><span class="n">environ</span><span class="p">)</span>
</code>
因为type(data)返回的是一个type类型,而函数不允许return一个type类型。改成这样:
return repr(type(data)) 可能是机制不一样,flask的视图返回字符串之类,就算你返回数字也是不行的,最近我也是在弄微信web那块,刚折腾的差不多,而且你那个公众号好像是个人未认证订阅号吧,开发者模式没有自定义菜单的,也就是缺少一个直接的web入口,还得通过消息发链接,挺麻烦的,限制很多,另外去stackoverflow搜索会更好点,基本都能找到答案 app.debug=True
可以看到详细错误 按规定这个要返回字符串,那你就要返回字符串,返回别的能用不说明任何问题,也不代表以后的版本仍然能用,当你返回不是字符串的时候就已经是未定义行为了,只是在web.py里面这个未定义行为刚好是可以用的而已 你可以打开debug模式。 来自 webpy 源码 webpy/utils.py
<code class="language-python"><span class="k">def</span> <span class="nf">safestr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s">'utf-8'</span><span class="p">):</span>
    <span class="sd">r"""</span>
<span class="sd">    Converts any given object to utf-8 encoded string. </span>
<span class="sd">    </span>
<span class="sd">        >>> safestr('hello')</span>
<span class="sd">        'hello'</span>
<span class="sd">        >>> safestr(u'\u1234')</span>
<span class="sd">        '\xe1\x88\xb4'</span>
<span class="sd">        >>> safestr(2)</span>
<span class="sd">        '2'</span>
<span class="sd">    """</span>
    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="nb">unicode</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">obj</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">encoding</span><span class="p">)</span>
    <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">obj</span>
    <span class="k">elif</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s">'next'</span><span class="p">):</span> <span class="c"># iterator</span>
        <span class="k">return</span> <span class="n">itertools</span><span class="o">.</span><span class="n">imap</span><span class="p">(</span><span class="n">safestr</span><span class="p">,</span> <span class="n">obj</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
</code>
我写的flask应用中,methods是写在app.route装饰器里面的。
类似这样
@app.route('/', methods=['GET', 'POST'])
def func(args):


要不这么改改试试?
Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn