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

SAP ABAP通过cl_http_client发送PUT/form-data请求报错排查

问题原因

报错的核心是两点:

  • multipart/form-data格式的请求必须在Content-Type头里携带随机生成的boundary边界参数,服务端靠这个值拆分不同的表单字段。你手动硬编码Content-Type: multipart/form-data没有带boundary,Flask无法解析请求体,直接抛出400格式错误。
  • CL_HTTP_CLIENT的SET_FORM_FIELD方法默认是为application/x-www-form-urlencoded格式设计的,不会自动生成multipart要求的分段请求体,就算手动补了boundary,请求体格式也不符合规范。
修正代码

场景1:需要传文件/必须使用multipart/form-data格式

不要手动设置Content-Type头,客户端会在构造multipart请求时自动填充带正确boundary的头值,参考代码:

" 前面创建CLIENT的逻辑保持不变
IF SY-SUBRC IS NOT INITIAL.
  " 原有错误处理逻辑保留
ENDIF.

" 设置请求方法
AO_HTTP_CLIENT->REQUEST->SET_METHOD( 'PUT' ).

" 仅保留鉴权头,删除手动设置Content-Type的代码
AO_HTTP_CLIENT->REQUEST->SET_HEADER_FIELD( 
  NAME = 'Authorization'
  VALUE = 'Basic Y292ZXN0cxxxxxxx3Zlc3Ryb19kZW1v'
).

" 构造multipart请求体
DATA(lo_multipart) = AO_HTTP_CLIENT->REQUEST->IF_HTTP_REQUEST~GET_MULTIPART( ).

" 添加第一个表单字段VAR1
DATA(lo_part1) = lo_multipart->ADD_PART( ).
lo_part1->SET_NAME( 'VAR1' ).
lo_part1->SET_DATA( 
  DATA         = '1'
  CONTENT_TYPE = 'text/plain'
).

" 添加第二个表单字段VAR2
DATA(lo_part2) = lo_multipart->ADD_PART( ).
lo_part2->SET_NAME( 'VAR2' ).
lo_part2->SET_DATA( 
  DATA         = '2'
  CONTENT_TYPE = 'text/plain'
).

" 发送请求、接收响应
AO_HTTP_CLIENT->SEND(
  EXCEPTIONS
    HTTP_COMMUNICATION_FAILURE = 1
    HTTP_INVALID_STATE         = 2
    HTTP_PROCESSING_FAILED     = 3
    OTHERS                     = 4
).
IF SY-SUBRC IS NOT INITIAL.
  " 发送错误处理
ENDIF.

AO_HTTP_CLIENT->RECEIVE(
  EXCEPTIONS
    HTTP_COMMUNICATION_FAILURE = 1
    HTTP_INVALID_STATE         = 2
    HTTP_PROCESSING_FAILED     = 3
    OTHERS                     = 4
).
IF SY-SUBRC IS NOT INITIAL.
  " 接收错误处理
ENDIF.

" 读取响应内容
DATA(lv_response) = AO_HTTP_CLIENT->RESPONSE->GET_CDATA( ).

场景2:仅传普通键值对、不需要传文件

这种场景没必要用multipart格式,直接用application/x-www-form-urlencoded格式即可,代码更简单,Flask也能正常解析:

" 前面创建CLIENT、设置PUT方法、设置鉴权头的逻辑不变
" 设置正确的表单格式头
AO_HTTP_CLIENT->REQUEST->SET_HEADER_FIELD( 
  NAME  = 'Content-Type' 
  VALUE = 'application/x-www-form-urlencoded'
).

" 直接用SET_FORM_FIELD传字段即可
AO_HTTP_CLIENT->REQUEST->SET_FORM_FIELD( NAME = 'VAR1' VALUE = '1' ).
AO_HTTP_CLIENT->REQUEST->SET_FORM_FIELD( NAME = 'VAR2' VALUE = '2' ).

" 后续SEND、RECEIVE逻辑和上面一致
Flask端注意事项
  • 两种表单格式发送的请求,在Flask端都通过request.form获取字段值,不要用request.get_json()读取,否则会报解析错误。
  • 如果需要传文件,在multipart场景下调用part的SET_FILE方法传入二进制文件内容、文件名即可,不需要额外修改请求头。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 13:09:28