如何在IBM i上通过QSYS2.HTTP_POST_BLOB_VERBOSE上传大CSV文件?
用RPG调用QSYS2.HTTP_POST_BLOB_VERBOSE上传CSV到Broadsign API的问题排查与解决
问题背景
需通过API上传150MB CSV文件至Broadsign平台,该请求在Postman CLI及Python代码中验证可行,但在IBM i环境下用RPG调用QSYS2.HTTP_POST_BLOB_VERBOSE时出现异常。
错误现象
- 携带含
bssta=true的完整Cookie时,返回401未授权,提示Cookie参数异常; - 移除
bssta=true后,返回400请求错误,提示服务器无法识别请求。
当前RPG代码
D SNDURL S SQLTYPE(CLOB:2048) D SNDHDR S SQLTYPE(CLOB:8192) D SNDBDY S SQLTYPE(CLOB:16773100) D RSPHDR S SQLTYPE(CLOB:65535) CCSID(1208) D RSPBDY S SQLTYPE(BLOB_FILE) D csvFile S SQLTYPE(BLOB_FILE) D url S 100A D options s 1000A url ='https://direct.broadsign.com/api/v1/audience/csv'; options= '{"headers":{"Content-Type":"text/csv",' + '"Accept":"application/json",' + '"Cookie":" bssta=true; session='+%TRIM(token) + '"}}'; RSPBDY_Name = '/ifspath/response.txt'; RSPBDY2_NL = %LEN(%TRIMR(RSPBDY_Name)); RSPBDY2_FO = SQFOVR; csvFile_Name = '/ifspath/audience.csv'; csvFile_NL = %LEN(%TRIMR(csvFile_Name)); csvFile_FO = SQFRD; SNDURL_DATA = %TRIM(URL); SNDURL_LEN = %LEN(%TRIMR(SNDURL_DATA)); SNDHDR_DATA = %TRIM(options); SNDHDR_LEN = %LEN(%TRIMR(SNDHDR_DATA)); exec sql SELECT RESPONSE_MESSAGE, CAST(RESPONSE_HTTP_HEADER AS CLOB(1000000)) INTO :RSPBDY, :RSPHDR FROM TABLE( QSYS2.HTTP_POST_BLOB_VERBOSE( CAST(:SNDURL AS VARCHAR(2048)), :csvFile, CAST (:SNDHDR AS CLOB(10K))));
排查方向与解决方案
1. 修正Cookie格式问题
- 移除Cookie值前的空格:当前代码中
"Cookie":" bssta=true; session='+%TRIM(token) + '"的bssta=true前有多余空格,这会导致服务器解析Cookie失败,修改为:options= '{"headers":{"Content-Type":"text/csv",' + '"Accept":"application/json",' + '"Cookie":"bssta=true; session='+%TRIM(token)+'"}}'; - 处理token特殊字符:如果token包含分号、空格等特殊字符,需用
%URL_ENCODE函数编码后再拼接,避免Cookie结构被破坏:'"Cookie":"bssta=true; session='+%URL_ENCODE(%TRIM(token))+'"}}';
2. 验证请求头JSON格式
- 将生成的
SNDHDR_DATA输出到文件,对比Python/Postman中的请求头JSON,检查是否存在引号不匹配、逗号遗漏等格式错误。 - 确认CSV文件编码与
Content-Type匹配:如果CSV是UTF-8编码,可尝试显式添加charset=utf-8:'"Content-Type":"text/csv; charset=utf-8",' +
3. 优化BLOB_FILE传输配置
- 指定文件CCSID:若CSV为UTF-8编码,需确保
csvFile的CCSID设置为1208,避免编码转换导致文件内容异常,可在定义时补充:D csvFile S SQLTYPE(BLOB_FILE) CCSID(1208) - 启用分块传输:在请求头中添加
"Transfer-Encoding":"chunked",确保大文件被正确分块发送:options= '{"headers":{"Content-Type":"text/csv; charset=utf-8",' + '"Accept":"application/json",' + '"Transfer-Encoding":"chunked",' + '"Cookie":"bssta=true; session='+%TRIM(token)+'"}}';
4. 对比请求细节定位差异
- 用抓包工具捕获Python/Postman和RPG的请求,重点对比:
- 请求头的所有字段(包括Cookie、Content-Length、Transfer-Encoding等);
- 请求体的传输格式(是否存在额外的边界标识或编码差异);
- HTTP协议版本(确认RPG使用的版本与Python/Postman一致)。
5. 简化请求做最小验证
- 先上传1MB以内的测试CSV文件,排除大文件传输的特殊问题;
- 硬编码已知有效的Cookie字符串到
options中,测试是否能成功上传,排除token拼接环节的错误。
内容的提问来源于stack exchange,提问作者baphomet
相关产品推荐
相关产品推荐

