React Native调用Microsoft Azure OCR API报Unsupported Media Type错误
解决React Native调用Azure OCR API时的"Unsupported Media Type"错误
嘿,我之前在React Native里调用Azure OCR API时也踩过这个坑!你遇到的Unsupported Media Type问题,核心原因是React Native的FormData处理逻辑和浏览器不一样,没法自动帮你搞定正确的请求头和文件格式,咱们来一步步解决它:
核心问题分析
你提到响应里的content-type显示为text/plain,这说明你的FormData没有被正确识别为文件上传请求。在浏览器里,FormData会自动生成带boundary参数的multipart/form-data请求头,但React Native里如果不手动指定文件的关键信息,它会默认把请求当成普通文本,这就触发了Azure API的格式校验错误。
解决方案1:正确构造FormData(推荐)
Azure的OCR API支持multipart/form-data格式上传图片,但你需要确保FormData里的文件字段包含完整的uri、name和type信息,同时不要手动设置Content-Type请求头(让fetch自动生成带boundary的正确头)。
举个完整的代码示例(假设你用react-native-image-picker获取图片):
import { launchImageLibraryAsync } from 'react-native-image-picker'; const uploadImageToOCR = async () => { // 1. 选择本地图片 const pickerResult = await launchImageLibraryAsync({ mediaType: 'photo', quality: 0.7, }); if (pickerResult.canceled) return; const selectedImage = pickerResult.assets[0]; const formData = new FormData(); // 2. 关键:给FormData添加文件时,必须指定name、type和uri formData.append('file', { uri: selectedImage.uri, name: `ocr-image-${Date.now()}.jpg`, // 随便指定一个带后缀的文件名 type: selectedImage.type || 'image/jpeg', // 匹配图片的MIME类型 }); try { // 3. 发起请求,不要手动设置Content-Type! const response = await fetch('https://<your-azure-resource>.cognitiveservices.azure.com/vision/v3.2/read/analyze', { method: 'POST', headers: { 'Ocp-Apim-Subscription-Key': '<你的Azure订阅密钥>', // 这里不要加 'Content-Type': 'multipart/form-data'! }, body: formData, }); if (!response.ok) { const errorText = await response.text(); throw new Error(`API Error: ${errorText}`); } const operationLocation = response.headers.get('Operation-Location'); // 注意:Azure Read API是异步的,需要根据Operation-Location轮询结果 const resultResponse = await fetch(operationLocation, { headers: { 'Ocp-Apim-Subscription-Key': '<你的Azure订阅密钥>', }, }); const ocrResult = await resultResponse.json(); console.log('OCR识别结果:', ocrResult); } catch (error) { console.error('请求失败:', error); } };
解决方案2:直接发送二进制流
如果你不想用FormData,也可以把图片转换成Blob,用application/octet-stream格式发送,这种方式更直接,也不容易出请求头问题:
// 把图片URI转换成Blob的工具函数 const uriToBlob = async (imageUri) => { const response = await fetch(imageUri); const blob = await response.blob(); return blob; }; const sendImageAsBinary = async (imageUri) => { const imageBlob = await uriToBlob(imageUri); try { const response = await fetch('https://<your-azure-resource>.cognitiveservices.azure.com/vision/v3.2/read/analyze', { method: 'POST', headers: { 'Ocp-Apim-Subscription-Key': '<你的Azure订阅密钥>', 'Content-Type': 'application/octet-stream', }, body: imageBlob, }); // 同样需要轮询Operation-Location获取结果 const operationLocation = response.headers.get('Operation-Location'); const resultResponse = await fetch(operationLocation, { headers: { 'Ocp-Apim-Subscription-Key': '<你的Azure订阅密钥>', }, }); const ocrResult = await resultResponse.json(); console.log('OCR识别结果:', ocrResult); } catch (error) { console.error('请求失败:', error); } };
关键注意点
- 不要手动设置
multipart/form-data头:手动设置会丢失fetch自动生成的boundary参数,这是Azure API识别多部分请求的关键。 - 文件字段必须指定
name和type:React Native的FormData需要这些信息才能把内容识别为文件,而不是普通文本。 - Azure Read API是异步的:第一次POST请求只会返回
Operation-Location,你需要用这个地址轮询获取最终的OCR结果。
内容的提问来源于stack exchange,提问作者Nate C
相关产品推荐
相关产品推荐

