【问题标题】:Returning JSON using a GET request from server使用来自服务器的 GET 请求返回 JSON
【发布时间】:2017-12-22 10:02:00
【问题描述】:

我有一个简单的服务器from here,当调用GET函数时,我希望它返回一个JSON文件,如下面的相关代码sn-p所示:

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import json

class S(BaseHTTPRequestHandler):
    def _set_headers(self):
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.end_headers()

    def do_GET(self):
        self._set_headers()
        with open('test.json') as data_file:    
            data = json.load(data_file)
        self.wfile.write(data)

我的 json 文件:

{"foo": "bar", "boo": "far"}

请求文件的应用程序(client.py):

import requests
import json

r = requests.get('http://localhost:8080')
print r.json()

但是,在尝试运行 client.py 时出现以下错误:

ValueError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

我是否在 do_GET 函数中正确加载了 test.json 文件?

感谢您的帮助:)

【问题讨论】:

  • 如果要将 JSON 传递回客户端,为什么要在服务器上解析它?就做with open('test.json') as data_file: self.wfile.write(data_file.read())
  • 现在可以使用了,谢谢!我知道我这样做很尴尬:/请随意提交它作为答案!

标签: python json python-requests


【解决方案1】:

让我们把答案做得更好一点:)

整个问题是您在服务器上解析test.json,然后将它的字符串表示形式打印到您的客户端。考虑一个简单的 JSON,例如:

{"foo": "bar", "baz": "far"}

当您将其加载并解析为 JSON,然后打印它时,您将得到一个 Python dict 的字符串表示,它被解析为,虽然非常相似,但不再是 JSON:

import json

data = '{"foo": "bar", "baz": "far"}'  # we'll use a string instead of a file for testing
parsed = json.loads(data)
print(parsed)  # equivalent to printing `str(parsed)`

哪个会产生(在 Python 2.x 上,在 Python 3.x 上没有 unicode 标记,但其余部分相同):

{u'foo': u'bar', u'baz': u'far'}

这就是从服务器发送数据的方式 - 作为 Python dict 的字符串表示形式。例如,请注意那些表示 unicode 字符串的 u 前缀?这些是罪魁祸首(在这种情况下)。

现在,如果您要加载它并尝试将其解析为 JSON:

import json 

data = "{u'foo': u'bar', u'baz': u'far'}"
parsed = json.loads(data)

您会收到 ValueError: Expecting property name: line 1 column 2 (char 1) 错误。

为避免这种情况,如果您想将 JSON 发送给您的客户端,请不要解析它,所以很简单:

with open('test.json') as data_file:
    self.wfile.write(data_file.read())

应该足够了。如果您需要对 JSON 进行一些预处理,则需要在发送之前将其序列化回 JSON,例如:

with open('test.json') as data_file:    
    data = json.load(data_file)
    data["boo"] = "baz"
    self.wfile.write(json.dumps(data))

【讨论】:

    【解决方案2】:

    json.load 不需要替换为data_file.read()

    def do_GET(self):
        self._set_headers()
        with open('test.json') as data_file:    
            data = data_file.read()
        self.wfile.write(data)
    

    【讨论】:

      【解决方案3】:

      为了能够使用 requests 库捕获来自 http.server 的 JSON 响应,或者使用 response.json() 的另一个词,您应该在服务器端进行以下操作:

      from http.server import BaseHTTPRequestHandler
      import json
      
      
      class GetHandler(BaseHTTPRequestHandler):
      
      def do_GET(self):
          json_data = {'token': 'qfrwefewrtweygds--fefef==wef'}
          json_to_pass = json.dumps(json_data)
          self.send_response(code=200, message='here is your token')
          self.send_header(keyword='Content-type', value='application/json')
          self.end_headers()
          self.wfile.write(json_to_pass.encode('utf-8'))
      

      这件事对我有用。

      【讨论】:

        猜你喜欢
        • 2016-06-03
        • 2018-03-05
        • 2023-03-07
        • 2013-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-24
        相关资源
        最近更新 更多