在Django中调用Microsoft Vision API遇415不支持媒体类型错误求助
解决Django调用Microsoft Vision API时的415 Unsupported Media Type错误
这个415错误本质是你发送给Vision API的请求格式不符合它的要求——API对请求的Content-Type头和数据格式有严格规定,咱们一步步来解决:
错误核心原因
Microsoft Vision API支持两种请求方式:
- 直接上传图片二进制数据:需要设置正确的图片MIME类型(比如
image/jpeg、image/png)作为Content-Type - 发送图片的公网URL:需要设置
Content-Type: application/json,并且请求体是包含url字段的JSON数据
你的代码大概率是没正确设置Content-Type,或者发送的数据格式不对。
针对Django上传图片的解决方案
假设你是把用户上传的图片(通过request.FILES获取的ImageField)发送给API,下面是修正后的代码示例:
import requests from django.contrib.auth.decorators import login_required from django.shortcuts import redirect, render from .forms import PostModelForm @login_required() def post_create(request): form = PostModelForm(request.POST or None, request.FILES or None) if form.is_valid(): instance = form.save(commit=False) instance.user = request.user instance.save() # 必须先保存实例,确保图片文件被写入服务器 # 配置Vision API参数 vision_base_url = "https://westcentralus.api.cognitive.microsoft.com/vision/v1.0/" analyze_url = f"{vision_base_url}analyze" subscription_key = "你的微软认知服务订阅密钥" # 读取上传图片的二进制数据 with instance.image.open('rb') as image_file: image_data = image_file.read() # 设置请求头:认证密钥 + 正确的Content-Type headers = { 'Ocp-Apim-Subscription-Key': subscription_key, 'Content-Type': instance.image.content_type # 自动获取图片的MIME类型,比如image/jpeg } params = { 'visualFeatures': 'Categories,Description,Color' } try: # 发送POST请求到Vision API response = requests.post(analyze_url, headers=headers, params=params, data=image_data) response.raise_for_status() # 主动抛出HTTP错误,方便调试 analysis_result = response.json() # 这里可以把API返回的结果保存到你的Post实例中 if analysis_result.get('description'): instance.caption = analysis_result['description']['captions'][0]['text'] instance.save() except requests.exceptions.HTTPError as e: print(f"调用Vision API失败:{str(e)}") # 这里可以添加错误处理逻辑,比如给用户返回提示 return redirect('post_detail', pk=instance.pk) return render(request, 'posts/create.html', {'form': form})
容易踩坑的几个点
- 必须先保存实例:Django的
ImageField在实例未保存前,文件可能还在内存中,无法通过open()正确读取二进制内容 - Content-Type不能乱设:如果是上传二进制图片,绝对不能用
application/json,必须用图片对应的MIME类型,或者通用的application/octet-stream - 区域和密钥要匹配:确保你的
vision_base_url中的区域(比如westcentralus)和订阅密钥的所属区域完全一致 - 读取文件要用二进制模式:必须用
open('rb')而不是默认的文本模式,否则会导致数据格式错误
内容的提问来源于stack exchange,提问作者B.dinesh
相关产品推荐
相关产品推荐

