ajax 请求后台连接中断

发布时间 2023-09-13 19:11:15作者: 郎中令

 

         日常开发中,当表单中的参数有url 类的跳转链接时,即使有部分特殊字符,一般也不会有问题,但总会有例外,导致提交表单的时候,ajax 会中断,

         机制大佬A: URL中包含双引号,编码后提交到后端,后端在解码后不会对字符串中的双引号加反斜杠进行转义,导致JSON反序列化异常。解决方案是在提交数据到后端前通过decodeURIComponent(url)进行解码后再提交。

         反驳: 有些url 链接本身无编码,类似 https://www.cnblogs.com/Sientuo/p/6245826.html , 有些url  本身可能经过多层转发,编码过n次,单纯的直接解码是不能满足需求的,类似:[https://xxxxx.baidu.com/?param=%7B%22title%22%3A%22%E3%80%90%E6%B5%8B%E8%AF%95%E3%80%9121Q3%E9%9B%B6%E5%94%AE%E5%90%AF%E5%8A%A8%E4%BC%9A%22%2C%22classesId%22%3A%22606%22%2C%22paperId%22%3Anull%2C%22qdStart%22%3A%222021-05-10%2014%3A00%22%2C%22qdEnd%22%3A%222021-05-10%2024%3A00%22%7D

         机制大佬A: 有时间在处理.., 然后一直到架构离职后还挂着...

         仔细想来,该问题也不算复杂,也有切入点, 问题的源头其实在于 ajax 表单提交时,解析字符串因为有特殊字符被中断,那只要保证提交时没有特殊字符不被中断即可,这样一来,想法就更多了,

         方案A:  通过des 加解密,前端加密,后端解密

         方案B:通过base64转字符串,前端转,后端还原

          有了想法,自然是付诸于实际行动中,加解密自不必说,统一维护一套秘钥即可, 这里记录一下base64转码, 坑还是挺多的, 其一: js 自带的有  window.btoa 编码64, 但是不支持中文,如果url 随意输入一个中文,提交仍然过不了,会报开小差, 所以要考虑的地方有,中文,特殊字符,编码格式,首先编码字母有 ASCII 和非 ASCII 字符之分,做好兼容性也有必要,一般情况下 escape() 在处理部分字符时存在一些问题,并不是最佳的编码方式。 encodeURIComponent稍微靠谱一些

    function SetLinkCodeValue(resultData) {
        var routeId = libUIUtils.getUIObj("@appId").getValue();
        var linkUrl = libUIUtils.getUIObj("@linkUrl").getValue();
        if (encodeURIComponent(linkUrl).indexOf("%u") < 0) {
            //加密字符
            //编码无效 resultData.route_link_url = window.btoa(linkUrl);
            //编码无效 resultData.route_link_url = $.base64.encode(linkUrl);
            resultData.route_link_url = btoa(encodeURIComponent(linkUrl).replace(/%([0-9A-F]{2})/g,
                function toSolidBytes(match, p1) {
                    return String.fromCharCode('0x' + p1);
                }));
        }
    }
            //控制器处理
if (linkUrl != string.Empty && Regex.IsMatch(linkUrl, @"^[a-zA-Z0-9+/]*={0,3}$", RegexOptions.None)) { dataObj.route_link_url = Encoding.UTF8.GetString(Convert.FromBase64String(linkUrl)); }

 这两种组合,效果还不错,输入了大量的转码好多次的脚本,都正常