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

Swift UrlSession上传多图至Node.js后端仅收单图问题排查

问题:Swift上传多图到Node.js后端仅收到1张图片

我用Node.js后端,通过multer的fields方法配置接收名为externalImages的图片数组(最多10张),Postman测试正常返回上传的图片详情。但用Swift的URLSession构造multipart/form-data请求上传多图时,后端只能收到1张图片,不想用第三方库,附两端代码求问题原因及解决方法。

后端代码

router.post('/imagesTest',multer().fields([{ name: 'externalImages', maxCount: 10 }]),adminController.imagesTest)

exports.imagesTest = async (req, res) => {
  console.log(req.files['externalImages'])
  res.send(req.files['externalImages'])
};

原Swift代码

func imagesTest(imageDataArray : [Data]) -> AnyPublisher<APIResponse, Error> {
        print("================= TEST IMAGES ")
        let boundary = UUID().uuidString
        var request = URLRequest(url: URL(string: "\(Constants.baseUrl)/admin/imagesTest")!)
        request.httpMethod = "POST"
        request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
        request.httpBody = createMultiImageMultiPartBody(boundary: boundary, imageDataArray: imageDataArray)
        return URLSession.shared.dataTaskPublisher(for: request)
            .receive(on: RunLoop.main)
            .map({$0.data})
            .decode(type: APIResponse.self, decoder: JSONDecoder())
            .eraseToAnyPublisher()
    }

func createMultiImageMultiPartBody(boundary : String,imageDataArray : [Data]) -> Data {
            var body = Data()
    
            let mimetype = "image/jpg"
            
            for imageData in imageDataArray{
                body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
                body.append("Content-Disposition: form-data; name=\"externalImages\"; filename=\"\(Date().timeIntervalSince1970).jpg\"\r\n".data(using: String.Encoding.utf8)!)
                body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
                body.append(imageData)
                body.append("\r\n".data(using: String.Encoding.utf8)!)
                body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)
            }
            return body
        }

问题原因

问题出在Swift的createMultiImageMultiPartBody方法中:你在每遍历一张图片后就添加了请求结束边界--\(boundary)--\r\n,这会让multipart请求在第一张图片后就被标记为完整结束,后端解析时会忽略后续所有图片数据,因此只能收到第一张图片。

解决方法

将结束边界的代码移出循环,仅在所有图片都添加完成后再添加一次结束边界。循环内只需要添加分隔边界(--\(boundary)\r\n)来区分不同的图片字段。

修正后的Swift代码

func imagesTest(imageDataArray : [Data]) -> AnyPublisher<APIResponse, Error> {
        print("================= TEST IMAGES ")
        let boundary = UUID().uuidString
        var request = URLRequest(url: URL(string: "\(Constants.baseUrl)/admin/imagesTest")!)
        request.httpMethod = "POST"
        request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
        request.httpBody = createMultiImageMultiPartBody(boundary: boundary, imageDataArray: imageDataArray)
        return URLSession.shared.dataTaskPublisher(for: request)
            .receive(on: RunLoop.main)
            .map({$0.data})
            .decode(type: APIResponse.self, decoder: JSONDecoder())
            .eraseToAnyPublisher()
    }

func createMultiImageMultiPartBody(boundary : String,imageDataArray : [Data]) -> Data {
            var body = Data()
    
            let mimetype = "image/jpg"
            
            for imageData in imageDataArray{
                body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
                body.append("Content-Disposition: form-data; name=\"externalImages\"; filename=\"\(Date().timeIntervalSince1970).jpg\"\r\n".data(using: String.Encoding.utf8)!)
                body.append("Content-Type: \(mimetype)\r\n\r\n".data(using: String.Encoding.utf8)!)
                body.append(imageData)
                body.append("\r\n".data(using: String.Encoding.utf8)!)
                // 移除循环内的结束边界
            }
            // 所有图片添加完成后,添加一次结束边界
            body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)
            return body
        }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 21:10:20