如何在WSGI响应中包装普通的JSON内容?

发布于 2025-02-04 13:01:48 字数 2770 浏览 3 评论 0原文

我有一个Django WSGI(不是我的决定)网站,打电话给动态生成JavaScript。我将函数放在views.py中,并且正在接收请求并完成工作,但是返回值正在拒绝。

调用此函数的HTML(网页的JavaScript部分)确实如此:

  var jscript = document.createElement('script');
  jscript.id = 'generate';
  jscript.style.visibility = 'hidden';
  jscript.style.display = 'none';
  jscript.src = `/generate?callback=catchOptions${query}`;  // jsonp https://en.wikipedia.org/wiki/JSONP query is a list of parameters in query string format                                                                                
  if (document.getElementById("generate") == null)
      document.body.appendChild(jscript);  // javascript needs this to work properly             

有映射 /生成到 /generate_planet的地图文件(请参见下文)。进入该功能很棒。这是Djangoff拒绝的回报值。

Here is the function in views.py
from cgitb import reset
from django.shortcuts import render
from . import planetor
from django.http import JsonResponse

def generate_planet(request):
    res = planetor.generate(request.content_params, "/app/planetor/", "FRAMES=1")
    # res is JSON text, NOT a python dict
    return res

# res looks like this:`callback({'camera_location': '-30,-30,-30', 'camera_angle': '30', 'sun_color': '5,5,5', 'sun_position': '10000,0,-10000', 'planet_size': '20.06', 'background': 'background_2.jpg', 'planet': 'surface_1.jpg', 'clouds_size': '1.02', 'clouds': 'clouds_16.jpg', 'clouds_density': '0.80', 'atmosphere': 'iodine', 'atmosphere_density': '0.95', 'atmosphere_size': '1.03', 'moons': '4', 'moon_position': None, 'moon_size': None, 'moon': None, 'random_color': None, 'random_float': None, 'random_trans': None, 'star_system': 'Barnard', 'star_index': 'Zeta', 'planet_index': 'II', 'planet_type': 'Surface ', 'identity': '81654447928', 'designation': 'v_star_index v_star_system v_planet_index', 'clouds_file': 'clouds_16.jpg'})

该功能调用实际上有效,并且“ Planetor.generate()”运行。问题是,返回JSON(真正的JSONP)确实被Djangoff

Djangoff拒绝了以下:

Internal Server Error: /generate_planet
    Traceback (most recent call last):
      File "/usr/local/lib/python3.9/dist-packages/django/core/handlers/exception.py", line 47, in inner
        response = get_response(request)
      File "/usr/local/lib/python3.9/dist-packages/django/utils/deprecation.py", line 119, in __call__
        response = self.process_response(request, response)
      File "/usr/local/lib/python3.9/dist-packages/django/middleware/clickjacking.py", line 33, in process_response
        response.headers['X-Frame-Options'] = self.get_xframe_options_value(
    AttributeError: 'dict' object has no attribute 'headers'
    [05/Jun/2022 16:52:11] "GET /generate_planet? HTTP/1.1" 500 56694

它正在寻找可以包装在我确定的东西中的返回值,但是我找不到我一生)我可以构建一个和2)任何人使用djangoff这样做任何事情的示例的API文档

I have a Django WSGI (not my decision) website making a call to fetch dynamically generated JavaScript. I put the function in views.py and it's receiving the request and doing the work, but the return value is being rejected.

The HTML (JavaScript section of web page) that calls this function does it like this:

  var jscript = document.createElement('script');
  jscript.id = 'generate';
  jscript.style.visibility = 'hidden';
  jscript.style.display = 'none';
  jscript.src = `/generate?callback=catchOptions${query}`;  // jsonp https://en.wikipedia.org/wiki/JSONP query is a list of parameters in query string format                                                                                
  if (document.getElementById("generate") == null)
      document.body.appendChild(jscript);  // javascript needs this to work properly             

There's map file that maps /generate to /generate_planet (see below). Getting into the function works great. It's the return value that Djangoff is rejecting.

Here is the function in views.py
from cgitb import reset
from django.shortcuts import render
from . import planetor
from django.http import JsonResponse

def generate_planet(request):
    res = planetor.generate(request.content_params, "/app/planetor/", "FRAMES=1")
    # res is JSON text, NOT a python dict
    return res

# res looks like this:`callback({'camera_location': '-30,-30,-30', 'camera_angle': '30', 'sun_color': '5,5,5', 'sun_position': '10000,0,-10000', 'planet_size': '20.06', 'background': 'background_2.jpg', 'planet': 'surface_1.jpg', 'clouds_size': '1.02', 'clouds': 'clouds_16.jpg', 'clouds_density': '0.80', 'atmosphere': 'iodine', 'atmosphere_density': '0.95', 'atmosphere_size': '1.03', 'moons': '4', 'moon_position': None, 'moon_size': None, 'moon': None, 'random_color': None, 'random_float': None, 'random_trans': None, 'star_system': 'Barnard', 'star_index': 'Zeta', 'planet_index': 'II', 'planet_type': 'Surface ', 'identity': '81654447928', 'designation': 'v_star_index v_star_system v_planet_index', 'clouds_file': 'clouds_16.jpg'})

The function call actually works, and the "planetor.generate()" runs. The problem is, the return JSON (JSONP really) from this, is rejected by Djangoff

Djangoff spits out this:

Internal Server Error: /generate_planet
    Traceback (most recent call last):
      File "/usr/local/lib/python3.9/dist-packages/django/core/handlers/exception.py", line 47, in inner
        response = get_response(request)
      File "/usr/local/lib/python3.9/dist-packages/django/utils/deprecation.py", line 119, in __call__
        response = self.process_response(request, response)
      File "/usr/local/lib/python3.9/dist-packages/django/middleware/clickjacking.py", line 33, in process_response
        response.headers['X-Frame-Options'] = self.get_xframe_options_value(
    AttributeError: 'dict' object has no attribute 'headers'
    [05/Jun/2022 16:52:11] "GET /generate_planet? HTTP/1.1" 500 56694

It's looking for the return value to be wrapped in something I'm sure but for the life of my I can't find 1) any API documents for WSGIResponse to I can construct one and 2) examples of anyone doing anything like this with Djangoff

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦境 2025-02-11 13:01:48

我最终弄清楚了。

如果您将请求发送到Django,则是这样:

/my_request?key1=value1&key2=value2&key3=value3

通过任何方式(原始URL,表单提交,Ajax请求等),

在views.py中放置这样的函数。

    def my_request(request):
        selections = request.GET # <== this gets the query string paramaters as a dictionary
        # use the query string parameters as the parameters of the function for creating the answer to the request
        res = {"answer1":"value1","answer2":"value2"} # << python dictionary of answer 
        return JsonResponse(res)  # convert dictionary to JSON

请django捕获该请求并返回JSON答案,请 恢复JSONP,您只需要编码RAW JavaScript:

return 'callback({"answer1":"value1","answer2":"value2"})'

I eventually figured this out.

If you send a request to Django, like this:

/my_request?key1=value1&key2=value2&key3=value3

By whatever means (raw URL, form submit, ajax request, whatever)

To have Django catch that request and return a JSON answer put a function like this in views.py

    def my_request(request):
        selections = request.GET # <== this gets the query string paramaters as a dictionary
        # use the query string parameters as the parameters of the function for creating the answer to the request
        res = {"answer1":"value1","answer2":"value2"} # << python dictionary of answer 
        return JsonResponse(res)  # convert dictionary to JSON

If you want to get JSONP back, you'll have to just code the raw javascript:

return 'callback({"answer1":"value1","answer2":"value2"})'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文