nginx - URL编码查询字符串

时间:2016-08-18 15:29:50

标签: regex nginx urlencode

我有一个nginx反向代理,它需要传递它收到的查询字符串。但是它收到的这个查询字符串格式不正确,可以包含不是URL编码的JSON,即它包含大括号,即{},逗号,冒号和双引号!不幸的是,我无法控制这一点,这会导致下游服务器在解析字符串时发生barf。

有没有办法在代理之前对此字符串进行正确的URL编码?

我可以替换花括号,因为我知道使用config只会有一个实例:

if ($args ~* '(.*){"(.*)":"(.*)","(.*)":"(.*)","(.*)":"(.*)","(.*)":"(.*)","(?<group10>.*)":"(?<group11>.*)"}(?<group12>.*)') {
    set $args $1%7B%22$2%22%3A%22$3%22%2C%22$4%22%3A%22$5%22%2C%22$6%22%3A%22$7%22%2C%22$8%22%3A%22$9%22%2C%22${group10}%22%3A%22${group11}%22%7D${group12};
    rewrite (.*)$ $1;
}
proxy_pass http://127.0.0.1:8080;

但是,我事先并不知道JSON将拥有多少个字段,因此很难对上面的其他对象使用与上面相同的逻辑。

我还应该提一下,我不认为这与nginx url-decoding参数有关,因为我没有在proxy_pass中使用URI。

谢谢!

更新:目前,JSON对象似乎正在发送相同的属性,因此这就是我用作解决方法的方法。它非常可怕,如果属性的数量发生变化,它会破坏,但现在可以完成工作。

const Task = require('data.task')
const {chain, liftM2} = require('control.monads')
import {pipe, length, curry, prop, equals, tap} from 'ramda'

it.only('sign in', done => {
    const merge = curry((p, f, g, x) => liftM2(p, f(x), g(x)))

    const signIn = pipe(
        lift,
        chain(merge(equals,
            pipe(lift, map(prop('password'))),
            pipe(lift, map(prop('userName')), chain(getUserByUserName), map(prop('password')))
        ))
    )

    signIn({ userName: 'ron', password: '123' })fork(
        (err) => { console.log('error happens'); done(err) },
        matched => { expect(matched).to.eql(true); done() }
    )
})

const getUserByUserName = (id) => new Task((reject, result) => setTimeout(
    userName => userName === 'ron'
        ? reject('not found')
        : result({ userName: 'ron', password: '123' })
    , 0
))

请注意,由于这会返回超过9个正则表达式组,因此我必须为组10,11和12命名,否则它们将被解释为$ 1 +数字0,1或2。

有更强大的方法吗?

1 个答案:

答案 0 :(得分:0)

就个人而言,我不喜欢使用单个if语句的解决方案,因为它看起来不太可读,不灵活或易于维护。您可能会看到是否具有locationrewrite语句的组合,其中每个语句处理特定的编码情况,可能有效;请参阅http://mdoc.su/,了解内部重定向非常繁重的有趣项目,但我相信nginx可能会对间接总数有所限制。

否则,如果您无法修改后端,另一个选项是自动将行为不当的客户端和/或请求重定向到辅助后端,辅助后端的唯一目的是正确地重新编码字符串,提供X-Accel-Redirect HTTP响应标头作为其输出(根据http://nginx.org/r/proxy_ignore_headers),nginx将用于对实际后端进行后续内部重定向/请求。