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

使用win32com WinHTTP发送带NT认证的Form-Data POST请求(含文件)问题

How to Send NT-Authenticated Multipart/Form-Data POST with WinHTTP in Python

Let's fix your issue step by step—your core problem here is misunderstanding how multipart/form-data works with WinHTTP, and trying to use JSON where it doesn't belong. Here's what you need to do:

First, Why Your Current Code Fails

  • JSON Serialization Error: You're trying to use json.dumps() on a dictionary containing binary file data (from rb mode). JSON can't handle raw bytes, so this will always throw an error.
  • Text Mode File Error: Opening a PDF with r (text mode) tries to decode the binary content as a string, which fails because PDFs aren't plain text—you must use rb mode for binary files.

WinHTTP doesn't automatically handle multipart/form-data like the requests library does, so you need to manually construct the request body with proper boundaries and formatting.

Solution: Manually Construct Multipart/Form-Data Request

Here's a complete working example that handles the file upload and keeps the automatic NT authentication:

import win32com.client
import os
import random
import string

def generate_boundary():
    # Generate a random boundary string to separate form parts
    return '----WinHTTPPartBoundary' + ''.join(random.choices(string.ascii_letters + string.digits, k=16))

# Configuration
url = "YOUR_TARGET_URL_HERE"
file_path = r'C:\filename.pdf'
dataset_id = 9
date_str = "2018-04-16"

# Step 1: Generate boundary
boundary = generate_boundary()

# Step 2: Build multipart form parts
form_parts = []

# Add regular form fields
form_parts.append(f'--{boundary}\r\n'.encode('utf-8'))
form_parts.append(b'Content-Disposition: form-data; name="datasetid"\r\n\r\n')
form_parts.append(f'{dataset_id}\r\n'.encode('utf-8'))

form_parts.append(f'--{boundary}\r\n'.encode('utf-8'))
form_parts.append(b'Content-Disposition: form-data; name="date"\r\n\r\n')
form_parts.append(f'{date_str}\r\n'.encode('utf-8'))

# Add file part
file_name = os.path.basename(file_path)
form_parts.append(f'--{boundary}\r\n'.encode('utf-8'))
form_parts.append(f'Content-Disposition: form-data; name="file"; filename="{file_name}"\r\n'.encode('utf-8'))
form_parts.append(b'Content-Type: application/pdf\r\n\r\n')  # Use correct MIME type for your file
with open(file_path, 'rb') as f:
    form_parts.append(f.read())
form_parts.append(b'\r\n')

# Add closing boundary
form_parts.append(f'--{boundary}--\r\n'.encode('utf-8'))

# Combine all parts into a single request body
request_body = b''.join(form_parts)

# Step 3: Send the request with automatic NT authentication
h = win32com.client.Dispatch('WinHTTP.WinHTTPRequest.5.1')
h.SetAutoLogonPolicy(0)  # This enables automatic NTLM/Kerberos auth using current user credentials
h.Open('POST', url, False)
# Set correct Content-Type header with boundary
h.SetRequestHeader('Content-Type', f'multipart/form-data; boundary={boundary}')
# Send the raw binary request body
h.Send(request_body)

# Check response
print(f"Status: {h.Status} {h.StatusText}")
print("Response:", h.ResponseText)

Key Details Explained

  1. Boundary String: This is a unique separator that tells the server where one form field ends and the next begins. We generate a random one to avoid conflicts with content in your file or fields.
  2. Multipart Format: Each field (including the file) is wrapped with the boundary, followed by headers describing the field, then the content. The file part includes the filename and correct MIME type (adjust this if you're uploading a different file type, like image/png for images).
  3. Automatic NT Authentication: SetAutoLogonPolicy(0) tells WinHTTP to use the current Windows user's credentials for NTLM or Kerberos authentication—no manual username/password required, which matches your requirement.
  4. Binary Handling: We read the file in rb mode to keep it as raw bytes, and combine all parts into a single binary request body that WinHTTP can send correctly.

Troubleshooting Tips

  • If you get authentication errors, double-check that the current user has permission to access the target URL (WinHTTP uses your logged-in user's context).
  • Verify the MIME type for your file—using the wrong type might cause the server to reject the upload.
  • Ensure the boundary string in the Content-Type header exactly matches the one used in the request body.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:39:05