http 响应报文中 ContentType 里的编码方式是浏览器对内容的解码方式,还是服务器对内容的编码方式

274 天前
 rookiemaster

在 springboot 项目里,我有如下设置:

server:
  servlet:
    encoding:
      charset: GBK
      force-response: true

然后 Controller 如下:

@RestController
public class TmpController {
    @GetMapping("/test")
    public Result test() throws UnsupportedEncodingException {
        String hello =  "你好";
        String newhello = new String( hello.getBytes("GBK") , "GBK");
        System.out.println(newhello);
        return Result.success(newhello);
    }
}

就是我想把一个字符串用 gbk 编码发给浏览器,然后让浏览器用 gbk 解码,但是最后浏览器显示的是乱码,不知该如何解决。

2346 次点击
所在节点    程序员
23 条回复
chinaguaiu
273 天前
@rookiemaster #18
utf-32 类型的话,框架和浏览器都可能会出现问题,可能需要逐一排除。


框架问题
-----------
utf-32 这个编码类型用的比较少,开发者一般是直接使用 utf-8 的,所以你首先还是需要通过抓却流量确定框架真的按照你指定的 utf-32 格式进行了编码。windows 下建议使用 Wireshark 工具进行抓取分析。
我模拟帮你抓取了一下流量,如下代码和配置下:

// 配置:server.servlet.encoding.charset=utf-32
// server.servlet.encoding.force-response=true
@GetMapping("/hello-encode")
public String sayHelloByString() {
return "你好,世界。";
}

抓取到的流量分析出来框架没有直接使用 utf-32 进行编码,而是使用了 utf-32be 进行编码;同时,该报文中的 Content-type 仍然指定 charset=UTF-32 ,显然导致了浏览器乱码问题(浏览器是按照 charset 指定的格式进行解码的,除非格式不支持)。我的环境是 spring-boot 3.1.5 。


浏览器问题
-----------
如果确实框架确实使用了你指定的格式进行编码并且发送数据到浏览器,才进一步考虑浏览器是否支持该编码类型;如果该浏览器不支持报文中 charset 字段指定的编码类型,那么浏览器会忽略掉 charset 字段并按照算法选取一个编码格式进行解析,显然,也容易出现乱码。各家浏览器对这个默认选取的编码格式不一样,你可以在 F12 的开发者工具控制台中输入 document.charset 或者 document.characterset 查看当前使用的编码。

我使用谷歌浏览器,上述所说的响应报文返回到浏览器后发生了乱码,我在控制台输入 document.charset 显示编码类型为 windows-1252 ,显然我的浏览器不支持 utf-32 类型。
longbowape
273 天前
大概率是因为你的源代码文件是 utf-8 编码的
rookiemaster
273 天前
@chinaguaiu 谢谢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1017487

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX