栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

微服务部署,前端post请求出现UTF-8错误

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

微服务部署,前端post请求出现UTF-8错误

一、问题描述:

技术栈:nacos,gateway,security,auth2,swagger,mybatis,Spring Boot、Spring Cloud & Alibaba、Vue、Element

环境:

JDK >= 1.8 (推荐1.8版本)
Mysql >= 5.7.0 (推荐5.7版本)
Redis >= 3.0
Maven >= 3.0
Node >= 12
nacos >= 2.x.x 
sentinel >= 1.6.0

本地在idea上测试各个接口功能一切正常,但是打包部署之后出现问题,前台get请求数据没有问题,当post和pu请求携带中文字符时,出现错误,具体错误如下:

JSON parse error: Invalid UTF-8 start byte 0xb9; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Invalid UTF-8 start byte 0xb9

当后台java代码打jar包部署,前端部署使用nginx。

1、pom打包插件文件:
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    exec
                
                
                    
                        
                            repackage
                        
                    
                
            
2、nginx配置如下:
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;
		charset utf-8;

		location / {
			root   C:/Users/Administrator/Desktop/erp-package/erp-ui;
			try_files $uri $uri/ /index.html;
            index  index.html index.htm;
        }

		location /prod-api/{
			proxy_set_header Host $http_host;
			proxy_set_header X-Real-IP $remote_addr;
			proxy_set_header REMOTE-HOST $remote_addr;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_pass http://localhost:8088/;
		}

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}# requirepass 123456

二、尝试解决: 1、最先以为是jvm启动设置问题,修改启动设置 -Dfile.encoding=UTF-8 ;问题依旧如此。 2、本以为是nginx没有设置字符集的问题,charset utf-8加上之后还是同样的问题。 3、前台已经设置统一编码格式'application/json;charset=utf-8'; 如下代码所示
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  baseURL: process.env.VUE_APP_BASE_API,
  // 超时
  timeout: 10000
})
三、解决办法 分析:

Gateway的过滤器中会对Url进行二次编码,二次编码的时候可能会出现问题。

Gateway又是FluxWeb形式响应存在滑动窗口截取数据的问题呢?这样是不是就造成数据滑块内的中文被“拦腰截断”呢(utf-8一个中文3个字节)。

原因:

再二次进行uri编码的问题,不应该使用 bytes = bodyStr.getBytes(); 应该指定utf-8字符集 bytes = bodyStr.getBytes("UTF-8");

@Component
@ConditionalOnProperty(value = "security.xss.enabled", havingValue = "true")
public class XssFilter implements GlobalFilter, Ordered
{
    // 跨站脚本的 xss 配置,nacos自行添加
    @Autowired
    private XssProperties xss;

    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain)
    {
        ServerHttpRequest request = exchange.getRequest();
        // GET DELETE 不过滤
        HttpMethod method = request.getMethod();
        if (method == null || method.matches("GET") || method.matches("DELETE"))
        {
            return chain.filter(exchange);
        }
        // 非json类型,不过滤
        if (!isJsonRequest(exchange))
        {
            return chain.filter(exchange);
        }
        // excludeUrls 不过滤
        String url = request.getURI().getPath();
        if (StringUtils.matches(url, xss.getExcludeUrls()))
        {
            return chain.filter(exchange);
        }
        ServerHttpRequestDecorator httpRequestDecorator = requestDecorator(exchange);
        return chain.filter(exchange.mutate().request(httpRequestDecorator).build());

    }

    private ServerHttpRequestDecorator requestDecorator(ServerWebExchange exchange)
    {
        ServerHttpRequestDecorator serverHttpRequestDecorator = new ServerHttpRequestDecorator(exchange.getRequest())
        {
            @Override
            public Flux getBody()
            {
                Flux body = super.getBody();
                return body.buffer().map(dataBuffers -> {
                    DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
                    DataBuffer join = dataBufferFactory.join(dataBuffers);
                    byte[] content = new byte[join.readableByteCount()];
                    join.read(content);
                    DataBufferUtils.release(join);
                    String bodyStr = new String(content, StandardCharsets.UTF_8);
                    // 防xss攻击过滤
                    bodyStr = EscapeUtil.clean(bodyStr);
                    //
                    byte[] bytes = new byte[0];
                    try {
                        bytes = bodyStr.getBytes("UTF-8");
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
//                    byte[] bytesOrigin = bodyStr.getBytes();
//                    System.out.println(bytesOrigin.toString());
                    NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
                    DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
                    buffer.write(bytes);
                    return buffer;
                });
            }

            @Override
            public HttpHeaders getHeaders()
            {
                HttpHeaders httpHeaders = new HttpHeaders();
                httpHeaders.putAll(super.getHeaders());
                // 由于修改了请求体的body,导致content-length长度不确定,因此需要删除原先的content-length
                httpHeaders.remove(HttpHeaders.CONTENT_LENGTH);
                httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
                return httpHeaders;
            }

        };
        return serverHttpRequestDecorator;
    }

    
    public boolean isJsonRequest(ServerWebExchange exchange)
    {
        String header = exchange.getRequest().getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);
        return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE);
    }

    @Override
    public int getOrder()
    {
        return -100;
    }
}

成功解决:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/820950.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号