这是上下文:
问题是 DRF 视图(我正在使用
ListCreateAPIView
)需要 JSON 数据,因此我无法调用 request.data
来应用 zlib 解压缩。由于压缩数据,我收到格式错误的请求(400 Bad request):JSON parse error - 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte
问题是:我怎样才能实现这个功能?
据我目前发现,Django Gzip 中间件(参见。无法使用 Django Rest 框架发送压缩的 gzip 数据)仅提供压缩功能,而不提供解压缩功能。 我还了解到压缩可能会导致安全风险。 另外,Nginx 解压文档仅针对响应,而不针对请求。
我有点困惑,因为压缩数据以通过 HTTP 请求发送对我来说似乎并不愚蠢(或者是吗?),而且我没有找到太多关于如何实现这一目标的资源。 所以也许我在这里遗漏了一些重要的东西?
客户端压缩:
async postData(json_data) {
let headers = authHeader();
headers['Content-Encoding'] = 'gzip';
headers['Content-Type'] = 'application/json';
const data = json_data;
const gz_data = pako.gzip(JSON.stringify(data));
return axios
.post(API_URL + 'create/',
data,
{
headers: headers,
}
)
.then(response => {
return response.data;
})
}
在 Django 视图端:
class DataList(ListCreateAPIView):
serializer_class = DataSerializer
authentication_classes = [JWTAuthentication]
permission_classes = [IsAuthenticated]
def get_queryset(self):
# Filter transects based on user identity (token based)
queryset = Data.objects.filter(user=self.request.user)
return queryset
def post(self, request, format=None):
transect_data = request.data # Returns 400 Bad request due to malformed expected JSON because it is gzipped
压缩请求正文可能不是一个好主意。我个人不确定。参见:
但是如果您仍然认为值得这样做,那么在这种情况下要读取请求正文,您似乎可以使用
request.body
来获取字节字符串形式的正文。 (link) 然后,您可以将该字节字符串传递给知道如何解压缩 gzip 的函数,这可能会为您提供另一个字节字符串。然后你就可以使用json.loads(body_bytes.decode('utf-8'))
。