代码之家  ›  专栏  ›  技术社区  ›  Cyril N.

是否仅在产品上编码问题?

  •  0
  • Cyril N.  · 技术社区  · 10 年前

    我使用PlayFramework2.3构建了一个应用程序,在某个时候我上传了一个CSV文件并用它填充了一个数据库。

    在本地(127.0.0.1:9000)访问应用程序并进行上传时,一切正常,文件被上传、解析并添加到数据库中,没有任何问题。

    在生产过程中执行相同的程序,但所有重音字符都被替换为 �� .

    开发和生产之间的主要区别是:

    • 在DEV中,我直接从PlayFramework(本地服务器)访问应用程序
    • 在PROD中,我通过NGinx访问该应用程序,该应用程序会重定向到Play(代理)的本地实例。

    以下是详细信息:

    • CSV文件是UTF-8编码的(注意:当然,它与我测试的文件相同)
    • 到数据库的连接使用UTF-8-> db.default.url="jdbc:mysql://127.0.0.1/2leadin?characterEncoding=UTF-8"
    • 我测试了(使用Firefox),HTML页面以UTF-8格式返回

    最后,这里是我的NGinx配置:

    proxy_buffering    off;
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   X-Scheme "https";
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   Host $http_host;
    proxy_http_version 1.1;
    
    server {
            listen 80;
            server_name my.2lead.in;
            return      301 https://my.2lead.in;
    }
    
    server {
        listen               443;
        ssl                  on;
        root                 /var/www/2lead.in/errors/;
    
        # http://www.selfsignedcertificate.com/ is useful for development testing
        ssl_certificate      /ssl/2lead.crt;
        ssl_certificate_key  /ssl/2lead.key;
    
        # From https://bettercrypto.org/static/applied-crypto-hardening.pdf
        ssl_prefer_server_ciphers on;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # not possible to do exclusive
        ssl_ciphers 'EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA';
        add_header Strict-Transport-Security max-age=15768000; # six months
        # use this only if all subdomains support HTTPS!
        # add_header Strict-Transport-Security "max-age=15768000; includeSubDomains"
    
        keepalive_timeout    70;
        server_name my.2lead.in;
    
        # remove the robots line if you want to use wordpress' virtual robots.txt
        location = /robots.txt  { access_log off; log_not_found off; }
        location = /favicon.ico { access_log off; log_not_found off; }
    
        location /public {
            alias /var/www/2lead.in/my/public/;
            access_log off;
            log_not_found off;
        }
    
        location / {
            proxy_pass  http://127.0.0.1:9100;
        }
    
        location ~ /\.git {
            deny all;
        }
    
        error_page 502 @maintenance;
        location @maintenance {
            rewrite ^(.*)$ /error502.html break;
        }
    }
    

    我缺少什么,你知道为什么我只有PROD才有编码问题吗?我很确定这是因为NGinx,但我找不到原因。

    非常感谢。

    1 回复  |  直到 10 年前
        1
  •  1
  •   Community CDub    8 年前

    默认的Java字符集取决于语言环境,并取自 file.encoding 环境变量(请参见 this answer ). 这可能会导致不同机器上的行为差异,正如您所看到的那样。有两种修复方法,一种是权宜之计,另一种是更健壮、更便携的方法:

    • 确保您的服务器正在运行 -Dfile.encoding=UTF-8 (或与您的开发环境匹配的任何内容)
    • 确保所有文件操作都显式指定字符集,如 this answer 描写

    总之,依赖默认系统编码是脆弱的,在大多数情况下应该避免。