Express(TypeScript)中如何处理HTTP GET参数里的非ASCII字符?
问题分析与解决方案
责任界定
- 按照HTTP标准,URL路径中的非ASCII字符本就该用UTF-8编码成百分号形式(你当前用
encodeURIComponent生成的hello%20t%C3%A2nia是完全合规的),所以从规范角度,外部API应该兼容这种请求,返回400属于对方的兼容性问题。 - 但实际开发中,我们没法强制修改外部服务,所以多数时候得主动适配对方的要求。
具体解决方法
1. 转成纯ASCII字符发送
如果外部API只认纯ASCII参数,用转义库把带特殊字符的内容转成ASCII等价形式,比如tânia转成tania:
import unidecode from 'unidecode'; const userInput = 'hello tânia'; const asciiSafeInput = unidecode(userInput); const encodedPath = `/api/search/${encodeURIComponent(asciiSafeInput)}`; // 最终请求路径:foo/api/search/hello%20tania
2. 改用ISO-8859-1编码
有些老API只支持ISO-8859-1编码,手动转码后再生成路径:
function encodeToISO88591(str: string): string { const encoder = new TextEncoder('iso-8859-1'); const byteArr = encoder.encode(str); return Array.from(byteArr) .map(byte => `%${byte.toString(16).padStart(2, '0').toUpperCase()}`) .join(''); } const userInput = 'hello tânia'; const encodedPath = `/api/search/${encodeToISO88591(userInput)}`; // 编码后tânia会变成t%E2nia,符合ISO-8859-1格式
3. 把参数移到查询字符串
很多API对路径参数限制严格,但查询字符串的兼容性更好,换个方式传参:
const userInput = 'hello tânia'; axios.get('foo/api/search', { params: { query: userInput } }); // axios会自动处理查询参数的编码,大概率能绕过路径的字符限制
4. 直接确认外部API的规范
如果上面的方法都不管用,最直接的是找外部API的维护方,问清楚他们要求的参数编码规则,按对方要求调整即可。
内容的提问来源于stack exchange,提问作者dragonfly02
相关产品推荐
相关产品推荐

