You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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")
        })

关键说明

  1. 原代码直接返回requests响应对象,而Shiprocket的响应文本是二次序列化的JSON字符串,必须用json.loads()解析一次才能得到正常的Python字典。
  2. 解析后提取的invoice_url会自动消除转义字符,成为可直接访问的有效链接。
  3. 最终返回结构化的处理结果,前端可直接使用正确的URL。

内容的提问来源于stack exchange,提问作者Sins97

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 13:45:29