配置Nginx日志url encode问题


配置Nginx日志url encode问题

问题描述:

当自定义日志输出格式,需要输出http请求中url参数时,如果参数中包含中文,是会进行url encode的,所以输出都是编码后的字符串,比如我配置的:

log_format test_log escape=json '{ "timestamp": "$msec", '
    '"request": "$request",'
    '"name": "$arg_name",'
    '"uuid": "$http_uuid",'
    '"remoteAddr": "$remote_addr" }';

请求 http://192.168.108.130:80/lua?name=我是中文
arg_name输出时就会是这样子:

{ “timestamp”: “1740829638.783”, “request”: “GET /lua?name=%E6%88%91%E6%98%AF%E4%B8%AD%E6%96%87 HTTP/1.1”,“name”: “%E6%88%91%E6%98%AF%E4%B8%AD%E6%96%87”,
“uuid”: “-”,“remoteAddr”: “192.168.108.1” }

所以目的是需要把它url decode再输出

方法1-lua

首先需要安装Lua,具体可以网上找教程文章看下,这里只提及简要流程

安装lua所需模块包括:

  1. lua-nginx-module
  2. ngx_devel_kit
./configure --prefix=/usr/local/nginx \
    --pid-path=/var/run/nginx/nginx.pid \
    --lock-path=/var/lock/nginx.lock \
    --error-log-path=/var/log/nginx/error.log \
    --http-log-path=/var/log/nginx/access.log \
    --with-http_gzip_static_module \
    --http-client-body-temp-path=/var/temp/nginx/client \
    --http-proxy-temp-path=/var/temp/nginx/proxy \
    --http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
    --http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
    --http-scgi-temp-path=/var/temp/nginx/scgi \
    --with-http_stub_status_module \
    --with-http_ssl_module \
    --with-file-aio \
    --with-http_realip_module \
    --with-openssl=/usr/local/software/openssl-1.1.1w \
    --add-module=/usr/local/software/lua-nginx-module-0.10.27rc1 \
    --add-module=/usr/local/software/ngx_devel_kit-0.3.3

然后 make(注意,如果无需替换原nginx目录的内容,则只需要make,不需要make install,然后编译后的objs目录里,把nginx可执行文件copy过去即可,可以先把原来nginx可执行文件备份下)

另外需要本地先安装luajit,比如我安装的 luajit2-2.1-20240626

另外有可能会报错 resty 相关的错误,网上文章有提到用 lua_load_resty_core off; 解决,但是我实际测试无效,故按照错误提示又下载了相关的包:

  1. lua-resty-core
  2. lua-resty-lrucache

nginx.conf 中添加配置:lua_package_path “/usr/local/software/lua-resty-core-0.1.29/lib/?.lua;”;

安装完成之后,可以测试下lua:

location /lua {
    default_type 'text/plain';

    content_by_lua 'ngx.say("hello, lua")';
}

之后加上我们的url解析配置:

set $decoded_arg_name  '';
location /lua {
    default_type 'text/plain';

    content_by_lua 'ngx.say("hello, lua")';
    access_by_lua_block {
            local args = ngx.req.get_uri_args()
                if args.name then
                  local decoded_name = ngx.unescape_uri(args.name)
                   ngx.var.decoded_arg_name = decoded_name
                   ngx.log(ngx.ERR, "Decoded name: ", decoded_name) # 打印日志调试用
            end
        }
}

完整nginx配置代码如下:


#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
    log_format test_log escape=json '{ "timestamp": "$msec", '
    '"request": "$request",'
    '"name": "$decoded_arg_name",'
    '"uuid": "$http_uuid",'
    '"remoteAddr": "$remote_addr" }';
    #access_log  logs/access.log  main;
    access_log logs/test_access.log test_log;

    sendfile        on;
    #tcp_nopush     on;
    lua_load_resty_core off;
    lua_package_path "/usr/local/software/lua-resty-core-0.1.29/lib/?.lua;";

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;
        set $decoded_arg_name  '';
        #charset koi8-r;
        charset utf-8;
       
        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        } 
        location /lua {
            default_type 'text/plain';
            
            content_by_lua 'ngx.say("hello, lua")';
            access_by_lua_block {
                    local args = ngx.req.get_uri_args()
                        if args.name then
                          local decoded_name = ngx.unescape_uri(args.name)
                           ngx.var.decoded_arg_name = decoded_name
                           ngx.log(ngx.ERR, "Decoded name: ", decoded_name)
                    end
                } 
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

但加上上面这一部还不够,lua的输出日志,如果是非ascii码,会输出为十六进制字符串:像是:

{ “timestamp”: “1740835690.677”, “request”: “POST /lua?name=%E6%88%91%E6%98%AF%E4%B8%AD%E6%96%87 HTTP/1.1”,“name”: “\xE6\x88\x91\xE6\x98\xAF\xE4\xB8\xAD\xE6\x96\x87”,“uuid”: “testuuid”,“remoteAddr”: “192.168.108.1” }

对于这个问题,偏新版的nginx可以通过加上 escape=json解决:

log_format test_log escape=json '{ "timestamp": "$msec", '
    '"request": "$request",'
    '"name": "$decoded_arg_name",'
    '"uuid": "$http_uuid",'
    '"remoteAddr": "$remote_addr" }';

至此打印的日志则是中文了:

{ “timestamp”: “1740834963.209”, “request”: “POST /lua?name=%E6%88%91%E6%98%AF%E4%B8%AD%E6%96%87 HTTP/1.1”,“name”: “我是中文”,“uuid”: “testuuid”,“remoteAddr”: “192.168.108.1” }

方法2-set-misc-nginx-module

在nginx中添加此模块,下载模块包 set-misc-nginx-module-0.33 解压后,configure命令如下:

./configure --prefix=/usr/local/nginx \
    --pid-path=/var/run/nginx/nginx.pid \
    --lock-path=/var/lock/nginx.lock \
    --error-log-path=/var/log/nginx/error.log \
    --http-log-path=/var/log/nginx/access.log \
    --with-http_gzip_static_module \
    --http-client-body-temp-path=/var/temp/nginx/client \
    --http-proxy-temp-path=/var/temp/nginx/proxy \
    --http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
    --http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
    --http-scgi-temp-path=/var/temp/nginx/scgi \
    --with-http_stub_status_module \
    --with-http_ssl_module \
    --with-file-aio \
    --with-http_realip_module \
    --with-openssl=/usr/local/software/openssl-1.1.1w \
    --add-module=/usr/local/software/lua-nginx-module-0.10.27rc1 \
    --add-module=/usr/local/software/ngx_devel_kit-0.3.3 \
    --add-module=/usr/local/software/set-misc-nginx-module-0.33

以上添加模块的lua相关的两个模块,可能可以不用加,但我测试的时候没有去掉,这里可以看大家需求

然后 make(注意,如果无需替换原nginx目录的内容,则只需要make,不需要make install,然后编译后的objs里,把nginx可执行文件copy过去即可,可以先把原来nginx可执行文件备份)

更改 nginx.conf

set $decoded_arg_name  '';
set_unescape_uri $decoded_arg_name $arg_name;

再同样加上 escape=json

其他什么的都不用配置了,实现效果是一样的。

### vue-ueditor-wrap 后端配置项未加载的解决方案 当 `vue-ueditor-wrap` 的后端配置项未能正常加载时,通常可能是由于以下几个原因引起的:路径错误、跨域问题、服务器端接口异常或者前端初始化参数设置不当。以下是针对该问题的具体分析和解决方法。 #### 1. 配置文件路径检查 确保 UEditor 所需的配置文件路径正确无误。UEditor 使用的是基于 JSON 或者 PHP 文件的形式来定义上传图片或其他资源的相关配置[^1]。如果路径不正确,则可能导致无法加载到这些配置项。 ```javascript // Vue 组件中的初始化选项 ueConfig: { serverUrl: '/upload', // 确保此 URL 能够访问到后台处理程序 } ``` #### 2. 处理跨域请求 如果前后端分离部署,在开发环境中可能会遇到跨域问题。此时需要确认服务端是否允许来自客户端域名的 CORS 请求[^2]。可以通过修改 Nginx 配置或直接调整 Node.js/PHP 应用的服务端逻辑实现支持: 对于 Express 框架下的简单示例: ```javascript const express = require('express'); const cors = require('cors'); let app = express(); app.use(cors()); // 添加这一行启用全局跨域支持 app.post('/upload', (req, res) => { /* ... */ }); ``` #### 3. 核实后端 API 接口功能 验证 `/upload` 这样的接口地址是否可以成功返回预期的数据结构给编辑器实例化调用。一般情况下它应该是一个标准 RESTful Web Service 并遵循特定格式响应数据[^3]。 例如,假设我们采用 PHP 实现了一个基础版本的文件接收脚本如下所示: ```php <?php header('Content-Type: application/json;charset=utf-8'); if ($_SERVER['REQUEST_METHOD'] === 'POST') { $file = $_FILES["upfile"]; move_uploaded_file($file['tmp_name'], './uploads/' . basename($file['name'])); echo json_encode(['state' => 'SUCCESS']); } else { http_response_code(405); exit; } ?> ``` #### 4. 前端组件调试技巧 利用浏览器开发者工具网络面板观察是否有向指定 endpoint 发起 POST 请求以及其状态码与实际反馈内容是什么样式的。另外也可以通过打印日志的方式进一步排查潜在隐患所在位置[^4]。 最后提醒一点就是记得查看官方文档说明是否存在遗漏之处哦!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值