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

Azure Blob存储上传PDF时如何正确设置Content-Type?

问题:Azure Blob存储上传PDF时Content-Type被重置为application/octet-stream

我有一个简单的Web应用,用于接收PDF文件名并将该PDF文件上传至Azure Blob存储。相关代码如下:

class AzureUploader(web.RequestHandler):
    @gen.coroutine
    def _write_remotely(self):
        json_body = tornado.escape.json_decode(self.request.body)
        filename = json_body.get("filename")
        container_client = ContainerClient(
            f'https://{REMOTE_ACCOUNT}.blob.core.windows.net/',
            REMOTE_CONTAINER,
            credential=REMOTE_ACCESS_KEY
        )
        blob_client = container_client.get_blob_client(filename)

        blob_client.set_http_headers(content_settings=ContentSettings(content_type='application/pdf'))
        logging.info('PROPERTIES {}'.format(blob_client.get_blob_properties()))

        with open(os.path.join(json_body.get("path"), filename), "rb") as data:
            blob_client.upload_blob(data)

    @gen.coroutine
    def post(self):
        logging.info('UPLOAD ALL REQUEST RECEIVED')
        self._write_remotely()
        return

我需要将Content-Type设置为application/pdf(默认值为application/octet-stream)。从日志中可以看到,content_settings字段的content_type已被设置为application/pdf:

[I 230809 12:56:01 pdf_receipt_sender_to_azure:70] PROPERTIES {'name': '100099_20230807_1411_010_00339_0487970002881.PDF', 'container': 'invoices/documents', 'snapshot': None, 'version_id': None, 'is_current_version': None, 'blob_type': <BlobType.BLOCKBLOB: 'BlockBlob'>, 'metadata': {}, 'encrypted_metadata': None, 'last_modified': datetime.datetime(2023, 8, 9, 10, 56, 1, tzinfo=datetime.timezone.utc), 'etag': "0x8DB98C7389BE957", 'size': 37463, 'content_range': None, 'append_blob_committed_block_count': None, 'is_append_blob_sealed': None, 'page_blob_sequence_number': None, 'server_encrypted': True, 'copy': {'id': None, 'source': None, 'status': None, 'progress': None, 'completion_time': None, 'status_description': None, 'incremental_copy': None, 'destination_snapshot': None}, 'content_settings': {'content_type': 'application/pdf', 'content_encoding': None, 'content_language': None, 'content_md5': None, 'content_disposition': None, 'cache_control': None}, 'lease': {'status': 'unlocked', 'state': 'available', 'duration': None}, 'blob_tier': 'Hot', 'rehydrate_priority': None, 'blob_tier_change_time': None, 'blob_tier_inferred': True, 'deleted': False, 'deleted_time': None, 'remaining_retention_days': None, 'creation_time': datetime.datetime(2023, 8, 7, 12, 11, 16, tzinfo=datetime.timezone.utc), 'archive_status': None, 'encryption_key_sha256': None, 'encryption_scope': None, 'request_server_encrypted': True, 'object_replication_source_properties': [], 'object_replication_destination_policy': None, 'last_accessed_on': None, 'tag_count': None, 'tags': None, 'immutability_policy': {'expiry_time': None, 'policy_mode': None}, 'has_legal_hold': None, 'has_versions_only': None}

但上传请求的参数显示Content-Type又变回了application/octet-stream:

[I 230809 12:56:01 _universal:523] Request URL: 'https://app.blob.core.windows.net/invoices/documents/100099_20230807_1411_010_00339_0487970002881.PDF'
    Request method: 'PUT'
    Request headers:
        'Content-Length': '37463'
        'x-ms-blob-type': 'REDACTED'
        'If-None-Match': '*'
        'x-ms-version': 'REDACTED'
        'Content-Type': 'application/octet-stream'
        'Accept': 'application/xml'
        'User-Agent': 'azsdk-python-storage-blob/12.14.1 Python/3.7.9 (Linux-4.15.0-74-generic-x86_64-with-Ubuntu-16.04-xenial)'
        'x-ms-date': 'REDACTED'
        'x-ms-client-request-id': '5453fcf2-36a3-11ee-ae74-00505680a149'
        'Authorization': 'REDACTED'
    A body is sent with the request

解决方案

问题出在你先调用set_http_headers设置Content-Type,再执行upload_blob时,SDK会使用默认的application/octet-stream作为请求的Content-Type,覆盖之前设置的blob属性。正确做法是直接在upload_blob方法中指定content_settings参数,让上传请求携带正确的Content-Type。

修改后的_write_remotely方法代码:

@gen.coroutine
def _write_remotely(self):
    json_body = tornado.escape.json_decode(self.request.body)
    filename = json_body.get("filename")
    container_client = ContainerClient(
        f'https://{REMOTE_ACCOUNT}.blob.core.windows.net/',
        REMOTE_CONTAINER,
        credential=REMOTE_ACCESS_KEY
    )
    blob_client = container_client.get_blob_client(filename)

    with open(os.path.join(json_body.get("path"), filename), "rb") as data:
        # 直接在upload_blob中指定content_settings
        blob_client.upload_blob(
            data,
            content_settings=ContentSettings(content_type='application/pdf')
        )
    # 可选:上传完成后验证属性
    logging.info('PROPERTIES {}'.format(blob_client.get_blob_properties()))

修改后,上传请求的Content-Type会被设置为application/pdf,同时blob的元数据也会正确保存该值。如果需要覆盖已存在的blob,可在upload_blob中添加overwrite=True参数。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 20:00:05