Javascript 在发送POST数据时防止Safari规范化Unicode?

Javascript 在发送POST数据时防止Safari规范化Unicode?,javascript,rest,post,unicode,safari,Javascript,Rest,Post,Unicode,Safari,显然,Safari在发送POST数据时规范化了Unicode,而所有其他主流浏览器都只发送给定的内容 规范化似乎发生在数据通过网络发送之前,在数据上使用也不起作用(Safari强制NFC,不管给出了什么) 当请求带有重音字符的文件名时,这会成为一个问题,在NFC和NFD格式中,重音字符具有不同的代码点。这种解释基本上可以归结为“组合字符”与“预组合字符”(中) 话虽如此,如果一个API在后端不进行自身的规范化,并且需要一个字符串数组(文件名),那么在使用Safari时是否可以在前端发送正确的文件

显然,Safari在发送POST数据时规范化了Unicode,而所有其他主流浏览器都只发送给定的内容

规范化似乎发生在数据通过网络发送之前,在数据上使用也不起作用(Safari强制NFC,不管给出了什么)

当请求带有重音字符的文件名时,这会成为一个问题,在NFC和NFD格式中,重音字符具有不同的代码点。这种解释基本上可以归结为“组合字符”与“预组合字符”(中)

话虽如此,如果一个API在后端不进行自身的规范化,并且需要一个字符串数组(文件名),那么在使用Safari时是否可以在前端发送正确的文件名

Unicode规范化问题的一个示例:

const str='Rosé'
常量nfc=str.normalize()
常量nfd=str.normalize('nfd')
console.log(nfc==nfd)//false
console.log(nfc.codePointAt(3))//233
console.log(nfd.codePointAt(3))//101
console.log(nfc.codePointAt(4))//未定义
console.log(nfd.codePointAt(4))//769
一个最小的、可重复的示例:

请注意Chrome和Safari之间的控制台日志差异

const isCorrectForm=(path,form)=>path==path.normalize(`NF${form}`)
const fetchData=async()=>{
常量sourcePathC='\u00e9';/“é”
常量sourcePathD='\u0065\u0301';/“é”
待命https://httpbin.org/post', {
方法:“POST”,
标题:{
“内容类型”:“应用程序/json”
},
正文:JSON.stringify({
pathsFormC:[sourcePathC],
路径表单:[sourcePathD]
}),
})
.then((response)=>response.json())
。然后((数据)=>{
const responseData=JSON.parse(data.data);
const responsePathC=responseData.pathsFormC[0];
const responsePathD=responseData.pathsFormD[0];
console.log({
isSourcePathCFormC:isCorrectForm(sourcePathC,'C'),
isSourcePathDFormD:isCorrectForm(sourcePathD,'D'),
isResponsePathCFormC:isCorrectForm(responsePathC,'C'),
isResponsePathDFormD:isCorrectForm(responsePathD,'D'),
});
});
}

fetchData()也许这是一个简单的解决方案。我这么说可能是因为这没有在Safari上测试过(不幸的是)

const isCorrectForm=(path,form)=>path==path.normalize(`NF${form}`)
const fetchData=async()=>{
const sourcePathC=encodeURIComponent('\u00e9');/“é”
const sourcePathD=encodeURIComponent('\u0065\u0301');/“é”
console.log(sourcePathC、sourcePathD);
待命https://httpbin.org/post', {
方法:“POST”,
标题:{
“内容类型”:“应用程序/json”
},
正文:JSON.stringify({
pathsFormC:[sourcePathC],
路径表单:[sourcePathD]
}),
})
.then((response)=>response.json())
。然后((数据)=>{
const responseData=JSON.parse(data.data);
const responsePathC=decodeURIComponent(responseData.pathsFormC[0]);
const responsePathD=decodeURIComponent(responseData.pathsFormD[0]);
控制台日志(responsePathC,responsePathD);
console.log({
isSourcePathCFormC:isCorrectForm(sourcePathC,'C'),
isSourcePathDFormD:isCorrectForm(sourcePathD,'D'),
isResponsePathCFormC:isCorrectForm(responsePathC,'C'),
isResponsePathDFormD:isCorrectForm(responsePathD,'D'),
});
});
}

fetchData()
HéHé似乎是我自己在编辑这个问题时被这个问题困住了:我先是从Firefox(我的主浏览器)尝试,然后从Safari尝试,看看它是否确实是可复制的,然后从Safari发布……也许这个简单更改的副本可以起作用,但无法在Safari上测试它。编码可以工作,但需要访问更改后端。@jabacchetta是的,这样就需要更改后端。@jabacchetta如果这是Safari的内置功能,我不确定您是否只能从客户端绕过它。让我烦恼的是,您编写的
规范化似乎就在数据通过线路发送之前发生了…
。如果它发生在
Javascript
执行之后,那么有可能绕过这个客户端吗?是的,我得出的结论是,只做客户端是不可能的。事实上,编码是我向后端团队提出的建议。我不相信我们会在这里得到答案,所以我会继续奖励你。