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

Xero发票附件上传后图片损坏问题排查求助

问题:上传JPG至Xero发票后图片损坏无法展示

我写了一段PHP代码用来把JPG图片上传到Xero发票,代码如下:

$file_name = "set-chains-glyph_78370-1551.jpg";
$remoteFileUrl = 'https://example.com/path-to-remote-file.jpg'; 

// Download the remote file using file_get_contents
$remoteFileContents = file_get_contents($remoteFileUrl);

$base64FileContents = base64_encode($remoteFileContents); 

$attachmentData = [
    [
        'FileName' => $file_name,
        'MimeType' => 'image/jpeg', // Update MIME type if necessary
        'Content' => $base64FileContents,
    ]
];

// Construct the correct API endpoint for attaching the file to an invoice
$url = 'https://api.xero.com/api.xro/2.0/Invoices/' . $invoiceId . '/Attachments/' . $file_name;

$Fileheaders = [
    'Authorization' => 'Bearer ' . $accessToken,
    'Xero-Tenant-Id' => $tenantId,
    'Content-Type' => 'application/octet-stream', 
'application/octet-stream' for binary file uploads
];

$newClient = new OAuth2\Client(null, [
    'access_token' => $accessToken
]);

$attachmentResponse = $newClient->fetch($url, json_encode($attachmentData), 'POST', $Fileheaders);

现在图片能成功上传到Xero发票,但查看时显示损坏,求排查解决。


排查与修复方案
  • 错误核心:请求格式与Xero API要求不匹配
    你当前的代码把base64编码后的内容放在JSON结构里发送,但Xero的发票附件上传API(/Invoices/{InvoiceID}/Attachments/{FileName})要求直接发送原始二进制文件内容,而非JSON包裹的base64数据。同时请求头和发送方式也需要调整:
  1. 修正请求内容
    不需要将文件内容base64编码,直接使用file_get_contents获取的原始二进制数据作为请求体,不要用json_encode处理:

    // 移除base64编码步骤
    // $base64FileContents = base64_encode($remoteFileContents); 
    // 直接用原始二进制内容作为请求体
    $requestBody = $remoteFileContents;
    
  2. 修正请求头
    你的请求头里有多余的注释行,同时Content-Type可以对应图片的MIME类型(image/jpeg),或者保留application/octet-stream但要确保语法正确:

    $Fileheaders = [
        'Authorization' => 'Bearer ' . $accessToken,
        'Xero-Tenant-Id' => $tenantId,
        'Content-Type' => 'image/jpeg' // 也可保留application/octet-stream,删除多余注释
    ];
    
  3. 修正API调用方式
    调用fetch方法时,直接传入原始二进制内容作为请求体,不要用json_encode:

    $attachmentResponse = $newClient->fetch($url, $requestBody, 'POST', $Fileheaders);
    
  4. 额外检查点

    • 确认file_get_contents成功获取了完整的远程文件,可以通过var_dump(strlen($remoteFileContents))查看文件大小是否和原文件一致,避免下载不完整导致损坏。
    • 如果远程文件需要权限访问,确保file_get_contents能正确获取(可能需要添加上下文参数处理headers或认证)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 06:23:25