美文网首页程序员开源工具技巧
alipay ILLEGAL_SIGN 错误解决

alipay ILLEGAL_SIGN 错误解决

作者: daydaygo | 来源:发表于2017-08-06 11:49 被阅读833次

    date: 2017-8-6 10:34:12
    title: alipay ILLEGAL_SIGN 错误解决

    大概是 2 周前周五遇到的问题吧,现在回想起来,当时追踪并解决问题的过程挺有意思的,记录下来给大家看看。

    事件回顾

    我们的产品提供消费分期的能力给航旅商户,当天下午 2 点,有一个商户反馈他们调起我们的 sdk 后选择 alipay 时,跳出支付宝 ILLEGAL_SIGN 提示页面。

    接到反馈后,我们进行了 alipay 的单元测试、自家机酒产品进入 sdk 后使用 alipay 以及使用商户传递过来的订单信息进行 alipay 单元测试,都没有复现这个问题。

    PS:支付系统我开发完,已经稳定运行 3 个月了,这是第一次收到这样问题的反馈。

    我们反馈给商户,希望商户确认一下自己的环境,我们也根据搜索引擎的结果,增加了:

    header("Content-type:text/html;charset=utf-8");
    

    随后配合商家测试,问题依旧存在。

    定位问题

    由于周五有各种例会(项目会、技术团队会、周报等),等到下午 6 点才有时间继续跟进。

    根据上面代码 charset=utf-8,我尝试用 chrome 的 Charset 插件,通过修改字符集为 GBK,终于稳定复现了这个问题。

    chrome-ext-charset charset-gbk

    其实就是确定了,问题出在 charset 上面。

    round one:fail

    于是,围绕 charset 做了多个尝试:

    • html 通过 meta 限定 charset
    • form 表单提交数据的 4 种格式,以及数据对应的编码
    <meta charset="UTF-8"> // html meta
    <form action="" method="post" enctype="multipart/form-data;charset=utf-8"></form>
    
    // http header 'Content-type' 标准形式
    Content-type: application/x-www-form-urlencoded; charset=UTF-8
    

    PS: http 协议中的 key 是不区分大小写的,所以写 'content-type' 也是可以的

    但是无论怎么改,还是会一直跳出支付宝 ILLEGAL_SIGN 提示页面。

    还是插件

    仔细一回顾,本来我这里是不会出现这个问题的,是通过chrome charset 插件才稳定复现的,于是又尝试用插件将 charset 改回 utf-8,果然好了!!!

    所以,这插件干了什么?!!!

    # show me the code
    git clone https://github.com/jinliming2/Chrome-Charset.git
    
    // 原来插件接管了所有请求
    chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
        if(tab.url.startsWith('file://') && changeInfo.status === 'complete' && localStorage.getItem('tab' + tabId)) {
            let xmlHttp = new XMLHttpRequest();
            xmlHttp.overrideMimeType('text/plain; charset=' + localStorage.getItem('tab' + tabId)); // 看这里
            xmlHttp.onload = () => {
                const is_html = /\.html?$/.test(tab.url);
                const data = is_html ? encodeURI(xmlHttp.responseText) : encodeURI(html_special_chars(xmlHttp.responseText));
                chrome.tabs.executeScript(tabId, {
                    code: `const _t = document.open('text/${is_html ? 'html' : 'plain'}', 'replace');
                    _t.write(${is_html ? `decodeURI('${data}')` : `'<pre>' + decodeURI('${data}') + '</pre>'`});
                    _t.close();`,
                    runAt: 'document_start'
                });
            };
            xmlHttp.onerror = () => {
                alert(chrome.i18n.getMessage('cannotLoadLocalFile'));
            };
            xmlHttp.open('GET', tab.url, true);
            xmlHttp.send();
        }
    }
    
    charset-code

    所以,果断禁用掉。

    PS: chrome 的「隐身模式」简直是调试神器,欢迎尝试。

    round two: fail

    禁用插件之后,继续按照 round one 的思路进行修改,然后,这问题就没办法复现了。

    所以,现在变成了 世纪难题 了:

    • 如果不启用 charset 插件,就无法复现问题了
    • 如果启动插件,所有 chrome 的请求都会被接管,修改的代码不会生效,也无法验证和修复问题

    final:月光就在眼前

    进入死胡同的时候,千万不要怀疑人生,你要相信:

    • 我书读得少,你不要骗我。
    • 那些看似无解的问题,往往只是你孤陋寡闻。
    • 知识这东西就是这样:知道就是知道,不知道就是不知道,所以还是多知道一点比较好

    所以,翻开了《http 权威指南》,仔细查阅之后,你就会发现,在 http协议里面,只有 2 个地方会影响到 charset:

    • 客户端:accept-charset='utf-8'
    • 服务端:content-type: text/plain;charset:utf-8

    所以,在代码里面修改为:

    <form id='alipaysubmit' name='alipaysubmit' accept-charset='utf-8'></form>
    

    晚上 10 点的月光,正好。

    相关文章

      网友评论

        本文标题:alipay ILLEGAL_SIGN 错误解决

        本文链接:https://www.haomeiwen.com/subject/lmmglxtx.html