Django集成Shiprocket API生成发票:URL转义致访问被拒问题
问题背景
在Django项目中调用Shiprocket API生成订单发票,已获取到成功响应,但返回的PDF发票URL包含转义字符(例如\/)。直接访问该URL会触发AccessDenied错误,手动移除转义字符后则可正常下载PDF。需要在代码中处理得到可直接使用的有效URL。
收到的响应
"{\"is_invoice_created\":true, \"invoice_url\":\"https:\/\/s3-ap-south-1.amazonaws.com\/kr-shipmultichannel-mum\/3116291\/invoices\/Retail000058ba9b309-c4bd-4c06-ba15-2cc76b7c5d1f.pdf\", \"not_created\":[],\"irn_no\":\"\"}"
访问URL时的错误信息
This XML file does not appear to have any style information associated with it. The document tree is shown below. <Error> <Code>AccessDenied</Code> <Message>Access Denied</Message> <RequestId>94ARWRYHGSBEZEH1</RequestId> <HostId>j32LvksmWatylm3TdFGYuJ1qvBwJ39Lj+qIbbQ3CC7AEcrgHnOYGd9fDocMeEwDD4GpzjXQLQhg=</HostId> </Error>
期望的有效URL格式
https://s3-ap-south-1.amazonaws.com/kr-shipmultichannel-mum/3116291/invoices/Retail000058ba9b309-c4bd-4c06-ba15-2cc76b7c5d1f.pdf
现有Views.py代码
class GenerateInvoice(APIView): def post(self, request): order_id = request.query_params.get("ids", None) print(order_id) data = json.dumps({"ids": [order_id]}) headers = { "Content-Type": "application/json", "Authorization": settings.SHIPROCKET_TOKEN, } url = "https://apiv2.shiprocket.in/v1/external/orders/print/invoice" response = requests.post(url=url, data=data, headers=headers) return Response(response)
解决方案
问题根源是Shiprocket返回的响应是双重JSON序列化的字符串,需先解析一次JSON得到正常字典,再提取invoice_url,转义字符会自动被处理。
修改后的代码如下:
import json from rest_framework.response import Response from rest_framework.views import APIView import requests from django.conf import settings class GenerateInvoice(APIView): def post(self, request): order_id = request.query_params.get("ids", None) print(order_id) data = json.dumps({"ids": [order_id]}) headers = { "Content-Type": "application/json", "Authorization": settings.SHIPROCKET_TOKEN, } url = "https://apiv2.shiprocket.in/v1/external/orders/print/invoice" response = requests.post(url=url, data=data, headers=headers) # 解析双重序列化的响应文本,得到正常字典 response_data = json.loads(response.text) # 提取自动去除转义的有效URL invoice_url = response_data.get("invoice_url", "") # 返回处理后的结构化数据 return Response({ "is_invoice_created": response_data.get("is_invoice_created"), "invoice_url": invoice_url, "not_created": response_data.get("not_created"), "irn_no": response_data.get("irn_no") })
关键说明
- 原代码直接返回
requests响应对象,而Shiprocket的响应文本是二次序列化的JSON字符串,必须用json.loads()解析一次才能得到正常的Python字典。 - 解析后提取的
invoice_url会自动消除转义字符,成为可直接访问的有效链接。 - 最终返回结构化的处理结果,前端可直接使用正确的URL。
内容的提问来源于stack exchange,提问作者Sins97
相关产品推荐
相关产品推荐

