点击此处---> 群内免费提供SAP练习系统(在群公告中)
加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)
大家好,
我需要通过HTTP Post上传内容类型为multipart/form-data的文件。 一切都很好,但是如果文件名是中文,它将变成乱码。
下面的屏幕截图是如何设置文件名的主要代码
我使用Tool Wireshark捕获HTTP流,在Wireshark中,您可以找到文件名变成乱码" ###"
遵循代码
FORM frm_upload_file使用pv_token TYPE字符串 pv_path TYPE字符串 pv_fname TYPE字符串 更改cv_flg TYPE c cv_msg TYPE字符串。 数据:lv_error_msg TYPE字符串, lv_url TYPE字符串, lv_body TYPE字符串, lv_asjson TYPE xstring, lv_str TYPE字符串。 数据:lo_http_client类型参考cl_http_client, lo_http_request类型参考cl_http_request, li_http_client类型参考if_http_client。 数据:lv_filename TYPE字符串, lv_filelength TYPE i,"上次文件长度 lv_header TYPE xstring, lv_length TYPE i。 "转成xstring后的长度 类型:开始于lty_xml, c(400)型x, lty_xml的结尾。 数据:lty_xml的lt_xml类型表, lv_xml_target TYPE xstring。 数据:lv_code TYPE字符串, lv_response_msg TYPE字符串。 cl_gui_frontend_services => gui_upload( 出口 文件名= pv_fname filetype ='BIN' 输入 文件长度= lv_filelength 标头= lv_header 改变 data_tab = lt_xml 例外情况 file_open_error = 1 file_read_error = 2 no_batch = 3 gui_refuse_filetransfer = 4 invalid_type = 5 no_authority = 6 unknown_error = 7 bad_data_format = 8 header_not_allowed = 9 spacer_not_allowed = 10 header_too_long = 11 unknown_dp_error = 12 access_denied = 13 dp_out_of_memory = 14 disk_full = 15 dp_timeout = 16 not_supported_by_gui = 17 error_no_gui = 18 )。 如果sy-subrc <> 0。 cv_flg ='E'。 cv_msg ='上传文件失败'。 返回。 万一。 通话功能'SCMS_BINARY_TO_XSTRING' 出口 input_length = lv_filelength 输入 缓冲区= lv_xml_target 桌子 binary_tab = lt_xml。 lv_length = xstrlen(lv_xml_target)。 CONCATENATE'http://'gv_ip'/fs/v1/upload/'INTO lv_url。 CONCATENATE lv_url'?access_token ='pv_token INTO lv_url。 呼叫方法cl_http_client => create_by_url 出口 网址= lv_url 输入 客户端= li_http_client 例外情况 arguments_not_found = 1 plugin_not_active = 2 internal_error = 3 其他= 4。 如果sy-subrc <> 0。 cv_flg ='E'。 cv_msg ='创建网址失败'。 返回。 万一。 *设置http方法POST 呼叫方法li_http_client-> request-> set_method( if_http_request => co_request_method_post)。 *设置协议版本 li_http_client-> request-> set_version( if_http_request => co_protocol_version_1_1)。 *内容类型 呼叫方法li_http_client-> request-> set_content_type 出口 content_type ='multipart/form-data'。 清除lv_str。 CONCATENATE'access_token ='pv_token INTO lv_str。 呼叫方法li_http_client-> request-> if_http_entity〜set_header_field 出口 名称=" Cookie" 值= lv_str。 呼叫方法li_http_client-> request-> if_http_entity〜set_header_field 出口 名称="接受" 值='text/html,image/gif,image/jpeg,*; q = .2,*/*; q = .2'。 呼叫方法li_http_client-> request-> if_http_entity〜set_header_field 出口 名称="内容类型" value ='multipart/form-data; charset = utf-8'。 **形体 数据:it_formulario TYPE tihttpnvp, wa_formulario喜欢它的行_formulario, 零件类型请参考if_http_entity。 "路径 部分= li_http_client-> request-> if_http_entity〜add_multipart()。 呼叫方法part-> set_header_field 出口 名称="内容处置" value ='form-data; name =" path"'。 呼叫方法part-> append_cdata 出口 数据= pv_path。 " filelen 部分= li_http_client-> request-> if_http_entity〜add_multipart()。 呼叫方法part-> set_header_field 出口 名称="内容处置" value ='form-data; name =" filelen"'。 lv_str = lv_length。 凝聚lv_str NO-GAPS。 呼叫方法part-> append_cdata 出口 数据= lv_str。 。 "文档名称 通话功能'SO_SPLIT_FILE_AND_PATH' 出口 full_name = pv_fname 输入 stripped_name = lv_filename * FILE_PATH = 例外情况 x_错误= 1 其他= 2。 如果sy-subrc <> 0。 返回。 *在这里实施适当的错误处理 万一。 清除lv_str。 CONCATENATE'form-data; Content-Type:application/octet-stream; charset = utf-8; name =" uploadfile"; filename ="'lv_filename'"'INTO lv_str。 部分= li_http_client-> request-> if_http_entity〜add_multipart()。 呼叫方法part-> set_header_field 出口 名称="内容处置" 值= lv_str。 *值= lv_xstr。 呼叫方法part-> append_data 出口 数据= lv_xml_target。 呼叫方法part-> set_content_type 出口 content_type ='text/html; charset = utf-8'。 呼叫方法li_http_client->发送 出口 超时= 200 例外情况 http_communication_failure = 1 http_invalid_state = 2 http_processing_failed = 3 其他= 4。 IF sy-subrc NE 0。 li_http_client-> get_last_error(IMPORTING消息= lv_error_msg)。 cv_flg ='E'。 cv_msg = lv_error_msg。 返回。 万一。 *接收响应对象 li_http_client-> receive(例外http_communication_failure = 1 http_invalid_state = 2 http_processing_failed = 3)。 如果sy-subrc <> 0。 li_http_client-> get_last_error(IMPORTING消息= lv_error_msg)。 cv_flg ='E'。 cv_msg = lv_error_msg。 返回。 万一。 lv_body = li_http_client-> response-> get_cdata()。 li_http_client-> close()。 清除lv_asjson。 使用lv_body lv_asjson执行frm_json_names_to_upper。 呼叫转换ID来源XML lv_asjson结果代码= lv_code消息= lv_response_msg。 如果lv_code ='0'。 cv_flg ='S'。 cv_msg ='上传成功'。 其他。 cv_flg ='E'。 cv_msg = lv_code &&':'&& lv_response_msg。 万一。wireshark-http-body-data.jpg (82.0 kB)
很难找到解决方案,但是可以将这个答案用作起点: https://stackoverflow .com/a/35573100/9150270
HTTP编码在RFC 5987中进行了说明( https://tools.ietf.org/html/rfc5987 ):标头字段可能包含以UTF-8表示且带有URL转义的值。 因此,应表示您(您好),它在UTF-8中对应于6个字节的E4 BD A0 E5 A5 BD,对应于URL转义%E4%BD%A0%E5%A5%BD的
内容处置在RFC 6266中进行了说明( https://tools.ietf.org/html/rfc6266 ):它说如果接收方不了解filename *,则可能需要同时提及filename和filename *(因为将中文名称翻译成US-ASCII字符听起来可能是不可能的,请选择任何通用名称)。
因此,您应该拥有(打招呼):
。
谢谢。 "文件名"标头字段听起来根本不是标准的,但是如果提供者理解它,那就很好了。
嗨,Guozheng,
由于构建您的问题的模型非常麻烦(因为我不知道整个过程和业务需求,所以甚至不可能),我只能提供3条建议:
我认为,方法 set_header_field 不够聪明,无法转换您的3? 字符中文文件名转换为UTF-8。
因此,它在Whireshark中显示为###(看起来像是将UTF-16转换为纯ASCII码)。
在将lv_filename添加为标头字段之前,尝试将其转换为UTF-8。
一周热门 更多>