SOAP-ERROR: Encoding: string … is not a valid utf-8 string

本文解决了PHP使用SOAP客户端调用Webservice时遇到的字符编码问题。问题表现为仅部分用户出现错误,原因是传输数据中存在特殊字符导致。通过设置SOAP客户端的编码为ISO-8859-1解决了该问题。

今天遇到一个错误,看标题就知道是什么错误了。。。。

最坑爹的是,不是所有的用户会报这个错误。只有少部分。在生产环境又没办法调试。

找了半天都不知道什么原因,字面意思大概是需要一个utf8编码的字符串,开始以为是文件编码没弄对,

后面改了编码还是无效。然后想办法打印了参数,发现里面有个字段有时候里会有特殊字符,导致有一

部分用户会报错,然后还是百度了一下soapClient,终于找到了,

PHP 利用SOAP调用webservice 传输汉字数据时,开发环境使用GBK模式,原来我这用的utf8,所有会报错,解决办法如下:

在第二个参数里添加

array('encoding'=>'ISO-8859-1')
$client = new \SoapClient($this->check_url,array('encoding'=>'ISO-8859-1'));

参考:http://www.cnblogs.com/xihong2014/p/5725182.html

@app.route('/send_email', methods=['POST']) def handle_send_email(): """接收前端请求并调用邮件函数""" try: data = request.get_json() print(data) sjr = data.get('sjr', '').strip() csr = data.get('csr', '').strip() tbbt = data.get('tbbt', '').strip() tbnr = data.get('tbnr', '').strip() fjr = data.get('fjr', 'IDS').strip() if not sjr or not tbbt or not tbnr: return jsonify({"success": False, "message": "缺少必要参数"}), 400 result = send_mail_soap(sjr=sjr, csr=csr, tbbt=tbbt, tbnr=tbnr, fjr=fjr) return jsonify(result) except Exception as e: return jsonify({"success": False, "message": f"服务器错误: {str(e)}"}), 500{'sjr': 'X2527715', 'csr': '', 'tbbt': '【健康报告】李婷 的体检数据 (2025/9/19)', 'tbnr': '\nimport requests import html import urllib3 # 忽略 SSL 警告 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) def send_mail_soap(sjr: str, csr: str, tbbt: str, tbnr: str, fjr: str): msgd = '''<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <ManualSend_08 xmlns="http://tempuri.org/"> <strMailCode>{0}</strMailCode> <strFormUser>{5}</strFormUser> <strRecipients>{1}</strRecipients> <strCopyRecipients>{2}</strCopyRecipients> <strSubject>{3}</strSubject> <strBody>{4}</strBody> </ManualSend_08> </soap:Body> </soap:Envelope>''' try: # HTML 转义防止 XML 错误 tbnr = html.escape(tbnr) tbbt = html.escape(tbbt) msgc = msgd.format("QFhky2Qfy8g=", sjr, csr, tbbt, tbnr, fjr) headers = { "Host": "ids.cdn.corpnet.auo.com", "Content-Type": "text/xml; charset=utf-8", "Content-Length": str(len(msgc)), "SOAPAction": "http://tempuri.org/ManualSend_08" } response = requests.post( "https://ids.cdn.corpnet.auo.com/ids_ws/mail.asmx", data=msgc, headers=headers, verify=False ) if response.status_code == 200: return {"success": True, "message": "邮件发送成功!", "response": response.text} else: return {"success": False, "message": f"HTTP {response.status_code}", "response": response.text} except Exception as e: return {"success": False, "message": f"请求异常: {str(e)}"}为什么会没有收到邮件
09-20
/****************************************************************************** * 函数名称: tr2_set_video_encoder_config_xml_to_json() * 函数描述: 解析tr2:SetVideoEncoderConfiguration请求的具体内容 * 输 入: soap -- soap结构体 * 输 出: json_req -- 根据请求构造的json object * 返 回 值: ERROR/OK ******************************************************************************/ LOCAL S32 tr2_set_video_encoder_config_xml_to_json(SOAP_CONTEXT *soap, JSON_OBJPTR *json_req) { S32 i = 0; JSON_OBJPTR json_obj = NULL; JSON_OBJPTR json_sec = NULL; JSON_OBJPTR json_opt = NULL; S32 request_len = 0; S32 ch = 0; char *xml_start = NULL; char *xml_str = NULL; char **p = NULL; char charbuf[LEN_INFO] = {0}; char attr_name[2][LEN_TAG] = {{"token"}, {"anyAttribute"}}; S32 name_str_len = sizeof(attr_name[0]); char attr_value_buf[2][LEN_ANY/2] = {{0}}; S32 value_str_len = sizeof(attr_value_buf[0]); void *ptrs_to_free[ONVIF_MAX_FREE_NUM] = {0}; TRT_SET_VIDEO_ENCODER_CONF set_config_cmd = {0}; char resolution[LEN_VALUE] = {0}; S32 frame_rate_limit = 0; S32 bitrate_limit = 0; S32 rate_control_flag = 1; VIDEO_CAP_MAIN video_cap_main = {{0}}; char *encode_type = NULL; S32 bitrate_type = -1; if (soap == NULL || json_req == NULL) { ONVIF_TRACE("soap == NULL."); return ERROR; } if (OK != soap_usernametoken_auth(soap, UM_OPERATOR)) { ONVIF_TRACE("Auth failed\n"); soap_fault(soap, "SOAP-ENV:Sender", "ter:NotAuthorized", NULL, "Authority failure"); soap->error = 400; return ERROR; } if (soap->request_begin != NULL && soap->request_end != NULL) { request_len = soap->request_end - soap->request_begin; if (request_len < 0) { ONVIF_TRACE("request_len < 0."); goto error_parse; } xml_str = xml_start = soap->request_begin; p = (char **)&xml_str; } else { ONVIF_ERROR("soap request content is NULL."); return ERROR; } while (((*p) - xml_start) < request_len) { if ((ch = soap_get_tag(xml_start, request_len, p, charbuf, sizeof(charbuf))) == EOF) { goto error_parse; } if (charbuf[0] == '/') { continue; } if (TRUE == soap_match_tag(charbuf, "Configuration")) { if (IS_WHITE_SPACE(ch)) { ch = soap_parse_element_attr_out_len(xml_start, request_len, p, 2, (char *)attr_name, name_str_len, (char *)attr_value_buf, value_str_len); if (strlen(attr_value_buf[1]) != 0) { json_obj = jso_from_string((const char *)attr_value_buf[1]); if (json_obj != NULL) { goto out; } } ONVIF_TRACE("token: %s", attr_value_buf[0]); if(0 != strcmp(attr_value_buf[0], "main") && 0 != strcmp(attr_value_buf[0], "minor")) { goto error_parse; } set_config_cmd.config = MALLOC_AND_REGISTER(TT_VIDEO_ENCODER_CONFIG, 1, ptrs_to_free, ONVIF_MAX_FREE_NUM); if (NULL == set_config_cmd.config) { goto error_parse; } set_config_cmd.config->token = MALLOC_AND_REGISTER(char, strlen(attr_value_buf[0]) + 1, ptrs_to_free, ONVIF_MAX_FREE_NUM); if (NULL == set_config_cmd.config->token) { goto error_parse; } strncpy(set_config_cmd.config->token, attr_value_buf[0], strlen(attr_value_buf[0]) + 1); } continue; } if (TRUE == soap_match_tag(charbuf, "Name")) { if (NULL == set_config_cmd.config) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("Name: %s", charbuf); set_config_cmd.config->name = MALLOC_AND_REGISTER(char, strlen(charbuf) + 1, ptrs_to_free, ONVIF_MAX_FREE_NUM); if (NULL == set_config_cmd.config->name) { goto error_parse; } strncpy(set_config_cmd.config->name, charbuf,strlen(charbuf) + 1); continue; } if (TRUE == soap_match_tag(charbuf, "UseCount")) { if (NULL == set_config_cmd.config) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("UseCount: %s", charbuf); set_config_cmd.config->use_count = atoi(charbuf); continue; } if (TRUE == soap_match_tag(charbuf, "Encoding")) { if (NULL == set_config_cmd.config) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("Encoding: %s", charbuf); if (0 == strcmp(charbuf, TR2_VIDEO_ENCODING_MIME_NAME_H264)) { encode_type = "H264"; } else if (0 == strcmp(charbuf, TR2_VIDEO_ENCODING_MIME_NAME_H265)) { encode_type = "H265"; } else { ONVIF_ERROR("Invalid encode type: %s", charbuf); goto error_parse; } continue; } if (TRUE == soap_match_tag(charbuf, "Resolution")) { if (NULL == set_config_cmd.config) { goto error_parse; } set_config_cmd.config->resolution = MALLOC_AND_REGISTER(TT_VIDEO_RESOLUTION, 1, ptrs_to_free, ONVIF_MAX_FREE_NUM); if (NULL == set_config_cmd.config->resolution) { goto error_parse; } continue; } if (TRUE == soap_match_tag(charbuf, "Width")) { if (NULL == set_config_cmd.config || NULL == set_config_cmd.config->resolution) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("Width: %s", charbuf); set_config_cmd.config->resolution->width = atoi(charbuf); continue; } if (TRUE == soap_match_tag(charbuf, "Height")) { if (NULL == set_config_cmd.config || NULL == set_config_cmd.config->resolution) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("Height: %s", charbuf); set_config_cmd.config->resolution->height = atoi(charbuf); continue; } if (TRUE == soap_match_tag(charbuf, "Quality")) { if (NULL == set_config_cmd.config) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("Quality: %s", charbuf); set_config_cmd.config->quality = atoi(charbuf); continue; } if (TRUE == soap_match_tag(charbuf, "RateControl")) { if (NULL == set_config_cmd.config) { goto error_parse; } if (IS_WHITE_SPACE(ch)) { char attr_in_name[20] = {"ConstantBitRate"}; char attr_out_buf[30] = {0}; int name_string_len = sizeof(attr_in_name); int value_string_len = sizeof(attr_out_buf); ch = soap_parse_element_attr_out_len(xml_start, request_len, p, 1, attr_in_name, name_string_len, attr_out_buf, value_string_len); if (EOF == ch) { ONVIF_ERROR("EOF == ch"); goto error_parse; } if (0 == strcmp(attr_out_buf, "true")) { bitrate_type = BITRATE_TYPE_CBR; } else if (0 == strcmp(attr_out_buf, "false")) { bitrate_type = BITRATE_TYPE_VBR; } } set_config_cmd.config->rate_control = MALLOC_AND_REGISTER(TT_VIDEO_RATE_CONTROL, 1, ptrs_to_free, ONVIF_MAX_FREE_NUM); if (NULL == set_config_cmd.config->rate_control) { goto error_parse; } continue; } if (TRUE == soap_match_tag(charbuf, "FrameRateLimit")) { if (NULL == set_config_cmd.config || NULL == set_config_cmd.config->rate_control) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("FrameRateLimit: %s", charbuf); set_config_cmd.config->rate_control->frame_rate_limit = atoi(charbuf); continue; } if (TRUE == soap_match_tag(charbuf, "BitrateLimit")) { if (NULL == set_config_cmd.config || NULL == set_config_cmd.config->rate_control) { goto error_parse; } if (OK != soap_parse_element_value(xml_start, request_len, p, ch, charbuf, sizeof(charbuf))) { goto error_parse; } ONVIF_TRACE("BitrateLimit: %s", charbuf); set_config_cmd.config->rate_control->bitrate_limit = atoi(charbuf); continue; } } /* bug #434969, 在大华NVR上有抓到SetVideoEncoderConfiguration中没有Configuratio内容的报文, * 为防止处理这样的异常报文时set_config_cmd.config为NULL空指针,增加以下判断防止系统崩溃*/ if(!set_config_cmd.config) { goto error_parse; } if(set_config_cmd.config->rate_control) { /* TODO: 比较是否超出最大值 */ /* if((minFr > req->Configuration->RateControl->frame_rate_limit) || (maxFr < req->Configuration->RateControl->frame_rate_limit) || (minBr > req->Configuration->RateControl->bitrate_limit) || (maxBr < req->Configuration->RateControl->bitrate_limit)) { return onvif_fault(soap, "SOAP-ENV:Sender", "ter:InvalidArgVal", "ter:ConfigModify", NULL); }*/ frame_rate_limit = (1 << 16) + set_config_cmd.config->rate_control->frame_rate_limit; bitrate_limit = select_appropriate_bitrate_limit(set_config_cmd.config->token, set_config_cmd.config->rate_control->bitrate_limit); if (ERROR == bitrate_limit) { goto error_parse; } } else { rate_control_flag = FALSE; } snprintf(resolution, LEN_VALUE, "%d*%d", set_config_cmd.config->resolution->width, set_config_cmd.config->resolution->height); ONVIF_TRACE("VideoPrama:%s,%d,%s,%d,%d\n", set_config_cmd.config->token, set_config_cmd.config->quality, resolution, frame_rate_limit, bitrate_limit); json_obj = jso_new_obj(); json_sec = jso_new_obj(); json_opt = jso_new_obj(); if (!json_obj || !json_sec || !json_opt) { ONVIF_ERROR("jso_new_obj fail."); jso_free_obj(json_obj); jso_free_obj(json_sec); jso_free_obj(json_opt); goto error_parse; } jso_obj_add(json_obj, "video", json_sec); jso_obj_add(json_sec, set_config_cmd.config->token, json_opt); if (encode_type) { jso_add_string(json_opt, "encode_type", encode_type); } jso_add_string(json_opt, "resolution", resolution); /* 设置quality时,DUT只支持1、3、5(低中高三挡),但外司NVR可支持更多选项, * 当DUT不支持设置的quality时,和SLP平台一致,就近保存为1、3、5三档。 */ if (0 == ds_read(VIDEO_CAP_MAIN_PATH, &video_cap_main, sizeof(VIDEO_CAP_MAIN))) { if ((VIDEO_QUALITY_S <= set_config_cmd.config->quality) && (VIDEO_QUALITY_L >= set_config_cmd.config->quality)) { jso_add_int(json_opt, "quality", set_config_cmd.config->quality); } } else { i = 0; while (QUALITYS_NUM > i) { if (set_config_cmd.config->quality >= video_cap_main.qualitys[i]) { ++i; } else { break; } } if (QUALITYS_NUM == i) { set_config_cmd.config->quality = video_cap_main.qualitys[QUALITYS_NUM - 1]; } else if (0 == i) { set_config_cmd.config->quality = video_cap_main.qualitys[0]; } else { set_config_cmd.config->quality = video_cap_main.qualitys[i - 1]; } jso_add_int(json_opt, "quality", set_config_cmd.config->quality); } if(rate_control_flag) { jso_add_int(json_opt, "frame_rate", frame_rate_limit); jso_add_int(json_opt, "bitrate", bitrate_limit); if (BITRATE_TYPE_CBR == bitrate_type) { jso_add_string(json_opt, "bitrate_type", "cbr"); } else if (BITRATE_TYPE_VBR == bitrate_type) { jso_add_string(json_opt, "bitrate_type", "vbr"); } } jso_add_string(json_obj, "method", "set"); out: *json_req = json_obj; free_ptrs(ptrs_to_free, ONVIF_MAX_FREE_NUM); return OK; error_parse: free_ptrs(ptrs_to_free, ONVIF_MAX_FREE_NUM); return ERROR; } 解释代码
09-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值