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

ReactNative 0.66.3上传相机图片到Azure表单识别器报错求正确写法

React Native 对接 Azure Form Recognizer 上传图片修复方案

原有代码核心错误点

  • 调用result.blob()时遗漏await关键字,导致实际传入的是Promise对象而非Blob实例,图片数据无效
  • 使用FormData提交时手动设置Content-Type: image/jpeg属于配置错误,FormData需要对应multipart/form-data类型,且该头不需要手动设置,fetch会自动生成带boundary的合法值
  • Azure Form Recognizer 预建收据接口不识别image_data字段,FormData提交时字段名必须为file
  • Base64提交时不能带data:image/jpeg;base64,前缀,必须传入纯base64编码的图片内容,否则会被判定为无效图片

可行实现方案

方案1:直接提交二进制Blob(最优,性能损耗最低)

不需要使用FormData,直接将图片Blob作为请求体即可:

export async function executeScanService(uri, base64data) {
  try {
    const url = 'https://<my-endpoint>/formrecognizer/v2.1/prebuilt/receipt/analyze';
    // 读取本地图片uri为Blob,补全await
    const imgResponse = await fetch(uri);
    const imgBlob = await imgResponse.blob();

    const options = {
      method: 'POST',
      headers: {
        'Ocp-Apim-Subscription-Key': '<替换为你的密钥>',
        'Content-Type': 'image/jpeg' // 直接传二进制时该配置正确
      },
      body: imgBlob
    };

    const response = await fetch(url, options);
    const respBody = await response.json();
    console.log('返回结果', respBody, response.status);
    return respBody;
  } catch (error) {
    console.error('扫描服务报错', error);
    throw error;
  }
}

方案2:Base64 数据提交

如果需要用已有的base64数据,可先转成Blob再提交:

export async function executeScanService(uri, base64data) {
  try {
    const url = 'https://<my-endpoint>/formrecognizer/v2.1/prebuilt/receipt/analyze';
    // 先移除base64前缀(如果有的话)
    const pureBase64 = base64data.replace('data:image/jpeg;base64,', '');
    const imgBlob = base64ToBlob(pureBase64, 'image/jpeg');

    const options = {
      method: 'POST',
      headers: {
        'Ocp-Apim-Subscription-Key': '<替换为你的密钥>',
        'Content-Type': 'image/jpeg'
      },
      body: imgBlob
    };

    const response = await fetch(url, options);
    const respBody = await response.json();
    console.log('返回结果', respBody, response.status);
    return respBody;
  } catch (error) {
    console.error('扫描服务报错', error);
    throw error;
  }
}

// 辅助函数:base64转Blob
function base64ToBlob(base64, contentType = '', sliceSize = 512) {
  const byteCharacters = atob(base64);
  const byteArrays = [];
  for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
    const slice = byteCharacters.slice(offset, offset + sliceSize);
    const byteNumbers = new Array(slice.length);
    for (let i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i);
    }
    byteArrays.push(new Uint8Array(byteNumbers));
  }
  return new Blob(byteArrays, {type: contentType});
}

FormData版本修复(如果必须使用FormData场景)

export async function executeScanService(uri, base64data) {
  try {
    const url = 'https://<my-endpoint>/formrecognizer/v2.1/prebuilt/receipt/analyze';
    const imgResponse = await fetch(uri);
    const imgBlob = await imgResponse.blob();

    const formData = new FormData();
    // 字段名必须为file,不能自定义为其他值
    formData.append("file", imgBlob, 'receipt.jpeg');

    const options = {
      method: 'POST',
      headers: {
        'Ocp-Apim-Subscription-Key': '<替换为你的密钥>'
        // 不要手动设置Content-Type,fetch会自动生成合法值
      },
      body: formData
    };

    const response = await fetch(url, options);
    const respBody = await response.json();
    console.log('返回结果', respBody, response.status);
    return respBody;
  } catch (error) {
    console.error('扫描服务报错', error);
    throw error;
  }
}

额外注意事项

  • iOS端如果读取本地file://协议的图片失败,需确认Info.plist中已配置相册/相机访问权限
  • 安卓端需确认已申请存储读取权限,targetSDK >=33时需要申请对应图片访问权限
  • 确认你的Azure Form Recognizer endpoint和密钥对应区域和服务版本匹配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 01:45:03