簡易實現(xiàn)
原理是通過sub_filter實現(xiàn)對callback的替換鸽心,具體配置如下:
nginx配置
location /www {
# 關(guān)鍵代碼:使用參數(shù)中的callback替換數(shù)據(jù)文件中的特定字串
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"
}
);
自適應(yīng)實現(xiàn)
思路如下:
- 在location中檢驗請求參數(shù)是否含有callback字段:如有則rewrite到一個專門的jsonp location。
- 在上述的rewrite中加入originpath參數(shù):用于記錄原始路徑居暖。
- 在jsonp location中使用ssi為返回json包裝外層callback函數(shù)顽频。
- 在jsonp location中使用sub_filter替換callback函數(shù)名。
- 在jsonp location中使用include的virtual屬性將原始的url包裹在返回json的內(nèi)層太闺。
- 為防止循環(huán)rewrite糯景,在jsonp location中將原始url中的callback參數(shù)刪除
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" -->
);