Nodejs中express与iOS ASI框架不兼容的问题

Nodejs中express与iOS ASI框架不兼容的问题

我学习nodejs没多久,现在用nodejs写App后台。感觉nodejs写后台那叫一个惬意啊。但是今天用iOS ASI上传图片的时候报错:

Error: unrecognized content-type: multipart/form-data; charset=utf-8; boundary=0xKhTmLbOuNdArY-76652528-14BC-449D-A06D-9D108EB591D7

大概就是说这个http的header.content-type无法识别,仔细查看出错位置

at Form.parse (…node_modules/express/node_modules/connect/node_modules/multiparty/index.js:105:23)。 var m = contentType.match(CONTENT_TYPE_RE); if (!m) { index.js:105:23 handleError(new Error('unrecognized content-type: ’ + contentType)); return; }

看到这里,实际上就是上面验证CONTENT_TYPE_RE的时候出问题。找到相应位置发现 var CONTENT_TYPE_RE = /^multipart/(form-data|related);\s*boundary=(?:"([^"]+)"|([^;]+))$/i; 查看这里发现这个正则表达式没有考虑content-type的charset这个属性,原因找到了。由于自己对正则表达式不是很熟悉,就搞了一个比较笨的方法来解决问题,大家不要见笑。 我添加一个带判断charset的正则表达式:

var CONTENT_TYPE_RE_WITH_CHARSET = /^multipart/(form-data|related);\scharset=utf-8;\sboundary=(?:"([^"]+)"|([^;]+))$/i;

然后先判断不带charset的正则表达式,再判断带charset的,这样就可以了。代码如下.

var m = contentType.match(CONTENT_TYPE_RE); if (!m) { m=contentType.match(CONTENT_TYPE_RE_WITH_CHARSET); if(!m){ handleError(new Error('unrecognized content-type: ’ + contentType)); return; } }

第一次发帖,请大家多多鼓励,谢谢。


3 回复

Nodejs中express与iOS ASI框架不兼容的问题

我学习Nodejs没多久,现在用Nodejs写App后台。感觉Nodejs写后台那叫一个惬意啊。但是今天用iOS ASI上传图片的时候报错:

Error: unrecognized content-type: multipart/form-data; charset=utf-8; boundary=0xKhTmLbOuNdArY-76652528-14BC-449D-A06D-9D108EB591D7

大概就是说这个HTTP的Content-Type头无法被识别。仔细查看出错位置:

at Form.parse (…node_modules/express/node_modules/connect/node_modules/multiparty/index.js:105:23)
var m = contentType.match(CONTENT_TYPE_RE);
if (!m) {
    handleError(new Error('unrecognized content-type: ' + contentType));
    return;
}

可以看到,实际上就是在验证CONTENT_TYPE_RE时出了问题。找到相应位置发现正则表达式如下:

var CONTENT_TYPE_RE = /^multipart\/(form-data|related);\s*boundary=(?:"([^"]+)"|([^;]+))$/i;

查看这里发现这个正则表达式没有考虑Content-Type中的charset属性,原因找到了。由于自己对正则表达式不是很熟悉,就搞了一个比较笨的方法来解决问题,大家不要见笑。

我添加一个带判断charset的正则表达式:

var CONTENT_TYPE_RE_WITH_CHARSET = /^multipart\/(form-data|related);\s*charset=utf-8;\s*boundary=(?:"([^"]+)"|([^;]+))$/i;

然后先判断不带charset的正则表达式,再判断带charset的,这样就可以解决问题。代码如下:

var m = contentType.match(CONTENT_TYPE_RE);
if (!m) {
    m = contentType.match(CONTENT_TYPE_RE_WITH_CHARSET);
    if (!m) {
        handleError(new Error('unrecognized content-type: ' + contentType));
        return;
    }
}

通过这种方式,可以确保Content-Type头即使包含charset属性也能被正确解析。希望这个解决方案对你有所帮助。

第一次发帖,请大家多多鼓励,谢谢。


应该是multiparty一个已经修正的bug:https://github.com/andrewrk/node-multiparty/issues/29

根据你的描述,你遇到了一个关于Content-Type头部中包含charset参数时导致的解析错误。你已经找到了问题并提供了一个解决方案,即使用两个正则表达式来处理这个问题。下面我会为你展示一个更简洁的方式来处理这种情况,并且避免重复代码。

解决方案

你可以通过扩展现有的正则表达式来处理charset参数,而不是增加一个新的正则表达式。这将使代码更加简洁和易于维护。

修改后的正则表达式

var CONTENT_TYPE_RE = /^multipart\/(form-data|related);\s*(charset=utf-8;\s*)?boundary=(?:"([^"]+)"|([^;]+))$/i;

在这个正则表达式中,charset=utf-8;\s*部分被放在一个可选的括号组中,这意味着charset可以存在也可以不存在。

使用修改后的正则表达式

var m = contentType.match(CONTENT_TYPE_RE);
if (!m) {
    handleError(new Error('unrecognized content-type: ' + contentType));
    return;
}

// 如果需要,你可以从匹配结果中提取其他信息

示例代码

假设你在multiparty/index.js文件中找到以下代码:

var CONTENT_TYPE_RE = /^multipart\/(form-data|related);\s*boundary=(?:"([^"]+)"|([^;]+))$/i;

module.exports = function(contentType, options) {
    var m = contentType.match(CONTENT_TYPE_RE);
    if (!m) {
        handleError(new Error('unrecognized content-type: ' + contentType));
        return;
    }
    // 其他逻辑...
};

你可以将其修改为:

var CONTENT_TYPE_RE = /^multipart\/(form-data|related);\s*(charset=utf-8;\s*)?boundary=(?:"([^"]+)"|([^;]+))$/i;

module.exports = function(contentType, options) {
    var m = contentType.match(CONTENT_TYPE_RE);
    if (!m) {
        handleError(new Error('unrecognized content-type: ' + contentType));
        return;
    }
    // 其他逻辑...
};

这样就可以正确处理包含charset参数的Content-Type头部了。希望这能解决你的问题!

回到顶部