通过Nginx实现JSONP

简易实现

原理是通过sub_filter实现对callback的替换,具体配置如下:
nginx配置

location /www {
        # 关键代码:使用参数中的callback替换数据文件中的特定字串
    sub_filter callback_20181229161611 $arg_callback;
    sub_filter_types application/json;
    sub_filter_once on;

    root                            html;
    index                       index.html index.htm;
}

json文件

//要被替换的字符串
callback_20181229161611(
{
    test: "ttlsa"
}
);

自适应实现

思路如下:

  1. 在location中检验请求参数是否含有callback字段:如有则rewrite到一个专门的jsonp location。
  2. 在上述的rewrite中加入originpath参数:用于记录原始路径。
  3. 在jsonp location中使用ssi为返回json包装外层callback函数。
  4. 在jsonp location中使用sub_filter替换callback函数名。
  5. 在jsonp location中使用include的virtual属性将原始的url包裹在返回json的内层。
  6. 为防止循环rewrite,在jsonp location中将原始url中的callback参数删除
location /www {
    rewrite ^(.*)\;jsessionid=(.*)$ $1 break;
    ssi                         on;
    ssi_silent_errors           on;
    ssi_types application/json;

    if ($query_string ~* %3c|%3e|%27 ){
        return 403;
    }

    if ($query_string ~ [\\\;\$\'\(\)]+){
        return 403;
    }

    if ($arg_callback) {
        rewrite ^ /jsonp/test1.json?orginalpath=$uri last;
    }

    root                        ../WebContent;
    index                       index.html index.htm;
}

location /jsonp {
    rewrite ^(.*)\;jsessionid=(.*)$ $1 break;
    ssi                         on;
    ssi_silent_errors           on;
    ssi_types application/json;

    if ($query_string ~* %3c|%3e|%27 ){
        return 403;
    }

    if ($query_string ~ [\\\;\$\'\(\)]+){
        return 403;
    }

    if ($args ~ "orginalpath=([^\&]*)\&(.*)callback=([^&]*)&?(.*)") {
        set $original_path $1;
        set $args1 $2;
        set $callbackv $3;
        set $args2 $4;

        set $virtual_path "${original_path}?${args1}${args2}";
    }

    sub_filter callback_20181229161611 $callbackv;
    sub_filter_types application/json;
    sub_filter_once on;

    root                        ../WebContent;
    index                       index.html index.htm;
}
callback_20181229161611(
<!--# include virtual="$virtual_path" -->
);

去除sub_module的支持

由于sub_module不是默认模块,所以使用ssi方案进行替换,jsonp外壳json变成如下形式:

<!--# echo var="callbackv" default="no" -->(
<!--# include virtual="$virtual_path" -->
);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容