返回响应代码python HTTP标头

时间:2014-08-08 05:43:57

标签: python

我有python服务器提供cgi脚本,

我想在状态代码中添加状态代码。我做了,

try:
     cgi = CGI()     
     output = cgi.fire()
     print 'Content-Type text/json'
     print 'Status:200 success'
     print
     print json.dumps(output)     
 except:
     print 'Content-Type: text/json'
     print 'Status: 403 Forbidden'
     print
     print json.dumps({'msg':'error'})

但是当我通过dojo xhr请求请求这个脚本时,我得到了200个请求状态。为什么会这样?

标题

Request URL:http://192.168.2.72:8080/cgi-bin/cgi.py
Request Method:POST
Status Code:200 Script output follows 
Request Headersview source
Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Content-Length:125
Content-Type:application/x-www-form-urlencoded
Host:192.168.2.72:7999
Origin:http://192.168.2.72:7999
Pragma:no-cache
Referer:http://192.168.2.72:7999/home.html
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Ubuntu Chromium/25.0.1364.160 Chrome/25.0.1364.160 Safari/537.22
X-Requested-With:XMLHttpRequest
Form Dataview sourceview URL encoded    
Response Headersview source
Content-Type:text/json
Date:Fri, 08 Aug 2014 05:16:29 GMT
Server:SimpleHTTP/0.6 Python/2.7.3
Status:403 Forbidden 

任何输入?

我已经尝试过的事情:

result.ioArgs.xhr.getAllResponseHeaders() // returns string
ioargs.xhr.status // returns the request status.

5 个答案:

答案 0 :(得分:6)

如果json.dumps(output)引发异常,您已经打印了包含状态代码(通常拼写为Status: 200 OK)的标题和一个空行以结束HTTP响应的标题部分。< / p>

然后,except块将打印第二组标题,但那些实际上被认为是该点响应主体的一部分,因为打印空行结束了标题。请参阅HTTP message规范。

解决方案是等到你知道打印任何标题的输出是什么。

<强> - 更多 -

如果您为其提供不可序列化的输入,

json.dumps可能会引发异常。鉴于cgi.fire()似乎是某个自定义CGI对象的方法(内置cgi模块没有该方法),它可能会返回任何内容。

要进行调试,您需要记录引发的异常,最好使用回溯。您所拥有的except:块将会捕获所有错误,然后不对它们执行任何操作,因此您不知道发生了什么,也没有人查看该问题。您可能还需要记录output的值。

答案 1 :(得分:2)

为了补充Jason S所说的我在his answer中完全复制的内容,我使用非json可序列化对象(在此示例中为md5哈希)再现了完全相同的故障,并且具有与原始海报相同的行为200返回代码

#!/usr/bin/env python

import json
import traceback
class CGI:
     def fire(self):
          import md5
          return md5.md5()
try:
     cgi = CGI()     

     output = cgi.fire()
     print 'Content-Type text/json'
     print 'Status:200 success'
     print
     print json.dumps(output)     
except:
     traceback.print_exc()
     print 'Content-Type: text/json'
     print 'Status: 403 Forbidden'
     print
     print json.dumps({'msg':'error'})

与服务器交互

$ socat - TCP4:localhost:8000 

输入

GET /cgi-bin/test.py HTTP/1.0

输出

HTTP/1.0 200 Script output follows
Server: SimpleHTTP/0.6 Python/3.4.0
Date: Sun, 17 Aug 2014 16:16:19 GMT
Content-Type text/json
Status:200 success

Content-Type: text/json
Status: 403 Forbidden

{"msg": "error"}

回溯:

127.0.0.1 - - [17/Aug/2014 18:16:19] "GET /cgi-bin/test.py HTTP/1.0" 200 -
Traceback (most recent call last):
  File "/home/xcombelle/dev/test/cgi-bin/test.py", line 16, in <module>
    print json.dumps(output)
  File "/usr/lib/python2.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python2.7/json/encoder.py", line 200, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python2.7/json/encoder.py", line 263, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib/python2.7/json/encoder.py", line 177, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <md5 HASH object @ 0x7fcb090d0a30> is not JSON serializable

答案 2 :(得分:1)

在输出标题之前,只需将json.dumps()转换为字符串,你应该没问题吗?

这将保护您不会设置标题,然后在打印时异常获得异常

答案 3 :(得分:1)

对于将来遇到此问题的任何人,其原因是用于提供内容的 python http.server。出于某种原因,这被设计为在 cgi 脚本开始运行之前吐出一个 Status 200: script output follows 标头。这意味着您无法更改脚本中返回的状态代码(请参阅 this page 上的 CGIHTTPRequestHandler 文档)

这实际上使开发时使用起来非常痛苦,因为错误不会以与生产中相同的方式传播。

答案 4 :(得分:-2)

我认为您正在设置Status:标题字段,但您想设置Status-Code:

您的脚本是否真的将Status Code:200 Script output follows写为标题字段?

相关问题