我在apache/2.4.29上运行一个api,它使用django rest框架3.10.3构建在运行在wsgi上的django 2.2.5之上,每当我试图为来自客户端的POST请求返回json对象时,描述成功的apiviews.py中的POST方法不会发送完整的数据。我试过使用卷发,邮递员和失眠症,反应是一样的。在日志中,它显示返回的Reponse对象被完全发送。这是apiviews.py代码:
from rest_framework import generics, status, viewsets, permissions
from rest_framework.response import Response
from rest_framework.views import APIView
from django.shortcuts import get_object_or_404, get_list_or_404
from django.contrib.auth import authenticate
import threading
import datetime
import json
from commons.models import SMSMessages
from commons.serializers import SMSMessagesSerializer
from notification.sender import sender
class SMSView(APIView):
def post(self, request):
sms_messages_serializer = SMSMessagesSerializer(
data={
"sms_number_to": request.data.get("sms_number_to"),
"sms_content": request.data.get("sms_content"),
"sending_user": request.auth.user_id,
}
)
permission_classes = (permissions.IsAuthenticated)
if sms_messages_serializer.is_valid():
data_to_send = {
"number": sms_messages_serializer.validated_data[
"sms_number_to"
],
"msg_text": sms_messages_serializer.validated_data[
"sms_content"
]
}
sms_object = sms_messages_serializer.save()
else:
print("invalid data - {0}\t{1}".format(sms_messages_serializer.errors, datetime.datetime.now()))
data_to_send = None
max_retry = 0
resp = Response()
while max_retry < 3:
max_retry += 1
status_flag, status_response = sender(data_to_send)
if not status_flag:
resp = Response(
data={
"status": "sms not sent"
},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
content_type="application/json"
)
else:
# the update method defined in the SMSMessagesSerializer class
# needs an instance to work with.
sms_messages_serializer.update(
sms_object,
{
"delivery_status": True
}
)
resp = Response(
data={
"status": "sms successfully sent"
},
headers=status_response.headers,
status=status_response.status_code,
content_type="application/x-www-form-urlencoded"
)
print(resp.data)
return resp
else:
resp = Response(
data={
"error": "unable to send sms"
},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
content_type="application/json"
)
print(resp.data)
return resp当sms成功发送时,它会在日志文件上打印出:
[Wed Dec 23 14:19:29.789772 2020] [wsgi:error] [pid 27330] [remote xxx.xxx.xxx.xxx:xxxx] {'status': 'sms successfully sent.'}但这不是交付给客户端的内容,客户端应用程序接收到:
{"status":"sms successfull为了更清晰起见,这是一个sender模块--它使用python库:
import requests
import time
import json
from rest_framework.response import Response
from rest_framework import status
base_url = "http://xxx.xxx.xxx.xxx:xxxx/"
def sender(sms_data):
"""
The actual function that accesses the server and sends the sms.
"""
sending_url = base_url + "api/sendsms/"
sending_headers = {"content-type": "application/x-www-form-urlencoded"}
response = requests.Response()
try:
response = requests.post(
sending_url,
data=sms_data,
headers=sending_headers,
timeout=(7, 14),
)
response.raise_for_status()
except Exception as e:
print("{}".format(e))
return False, response
else:
return True, response所有标头都完好无损,这只发生在成功响应上,其余的则不会出现。
如何使它向客户端发送完整的响应?
谢谢
发布于 2021-01-03 10:16:02
在成功响应上设置的标头通知错误的内容长度和内容类型。
您的响应目前是这样构建的:
resp = Response(
data={
"status": "success"
},
headers=status_response.headers,
status=status_response.status_code,
content_type="application/form-data"
)在这里,您从短信服务(如Content-Length )转发响应的头,而传输的内容是{"status": "success"}。
当构建的响应中没有提供Content-Length时,框架将根据传输的内容计算它。
还需要注意的是,传输的内容是JSON数据,而不是form-data。
如果您关心SMS服务响应中的任何特定标头,建议显式地选择将哪些标头发送回请求者,如下所示:
resp = Response(
data={
"status": "success"
},
headers={
"specific_header_name_passed_from_sms_service": status_response.headers["specific_header_name_passed_from_sms_service"],
#...
},
status=status_response.status_code,
content_type="application/json"
)否则,如果您不关心来自SMS服务的响应中的任何头部,则可以忽略在构建的响应中传递headers选项。
https://stackoverflow.com/questions/65426021
复制相似问题