CGI API 到 POST 使用 $.ajax() 而不是 $.getJSON() RPGLE IBM i PASE 环境
CGI API to POST using $.ajax() instead of $.getJSON() RPGLE IBM i PASE environment
您可以使用什么 CGI API 将 $.getJSON()
替换为 $(ajax)...POST
。在 IBM i 环境中使用 CGIDEV2 时,GET
用于所有内容(即:GET, PUT, POST, DELETE
)?我不想以传统方式传递我的参数,例如:$('[name="EMAIL"]').val()
而我想传递 JSON 对象字符串,例如:{"form" : [{ "email": "yardpenalty@yahoo.com"}]}
。
我们可以使用 CGIDEV2 使用 $.getJSON()
执行 PostToGet 回调,但我不能完全使用 $.ajax
。这是我们现在所做的,即所有 GET
个请求
PHP/JS:
// load all parameters
data = 'INSTANCE=<?echo trim($PATH_INSTANCE)?>' +
'&FUNCTION=<?echo urlencode(trim($FUNCTIONCODE))?>' +
'&USER=' + $('[name="USER"]').val() +
'&CONTACT=' + w$('[name="CONTACT"]').val() +
'&EMAIL=' + $("input[name='EMAIL']").val() +
'&MSG=' + $('[name="MSG"]').val() +
'&TYPE=' + $('[name="TYPE"]').val();
// Call the RPG REST JSONP program
$.getJSON( "http://www.domain.com:8082/rest/RPGLEPGM?callback=?",data )
.done(function( json ) { ... }
//Domain is actually
http://www.domain.com:8081
RPGLE PGM:
Begsr $Incoming;
cgiPostToGet(); // Convert POST to GET
callback = cgiParseGet('callback'); // callback
p#Function = cgiParseGet('FUNCTION');
Endsr;
但我希望能够使用其他 AJAX 方法执行各种操作,例如简单地即时更新记录 .post()/.ajax()
或简单的 .get()
ajax 调用无需创建回调。我不想每次使用 ajax 时都必须使用 getJSON 更不用说它在 GET 上对 POST 的不良做法,但据我了解 .getJSON()
提供 JSONP 功能,而其他默认情况下不提供。
编辑: 我们确实有我们的 ajax RPGLE PGMS 在与实际网站不同的端口所以 JSONP 是必要的并且客户知道它JSONP 因为我们将 callback
函数传回。
因为我们的 ajax RPGLE PGM CALLS 与 PHP 请求在不同的端口(想想主机服务器上的不同域),这符合跨域请求;因此,我们必须使用 JSONP(如果存在安全问题,则使用 Cors)将 &callback=?
function/wrapper 传回客户端。我在 SO 上的 JSONP 上找到了一篇非常好的文章,这正是这个 ajax 调用正在使用的内容。
RPGLE jQuery ajax 请求可以通过使用某种 CGI API 在您的 OS/400 - IBM i Web 环境中访问。当使用 ajax 调用(CALLB
或 CALLP
)一个 RPGLE PGM 时,我们实际上是在进行程序调用,但是当使用全局温度时,我们实际上是在进行 SQL 程序调用,它就资源而言更昂贵,这就是 Web 服务变得越来越流行的原因。
不仅根据请求从表单数据传递 javascript 对象,而且通过 Ajax 请求传递 return JSON 对象比存储全局临时数据更实用在 db2 环境中并将其处理为响应中的 PHP 数组。
通过在客户端处理 JSON 字符串,而不是同时使用服务器内存和驱动器 space 以及 PHP 数组和全局临时文件所需的磁盘 read/writes,我们真正能够利用更现代的网页设计实践。
这是一个在不使用 $.getJSON()
的情况下正确使用 $.ajax
/PHP/RPGLE 的工作示例:
<script>
$(document).ready(function(){
GetEmail("#email", '<?php echo trim($USER)?>', '<?php echo $PATH_INSTANCE?>');
FormValidation();
});
function FormValidation(){
//Variables created without the keyword var, are always global, even if they are created inside a function.
var form = $('#<?echo $PAGEID?>');
var FormError = $('.alert-danger',form);
var success = $('.alert-success',form);
form.validate({
focusInvalid: false, // do not focus the last invalid input
onkeyup: false,
ignore: ".ignore", //required for hidden input validation ie: hiddenRecaptcha
rules:{
"TYPE": {
required: true,
},
"MSG": {
required: true,
rangelength:[40,1000]
},
"CONTACT": {
required: {
depends: "#newuser:checked"
}
},
"EMAIL": {
required: true,
email: {
depends: function() {
if(!$("#newuser:checked"))
return true;
else
return false;
}
},
HTH_TelephoneEmail: {
depends: function() {
if($("#newuser:checked"))
return true;
else
return false;
}
}
},
hiddenRecaptcha: {
required: function () {
if (grecaptcha.getResponse() == '') {
return true;
} else {
return false;
}
}
}
},
messages: { // custom messages for form validation input
"TYPE": {
required: 'Please select an option as it pertains to your inquiry'
},
"MSG": {
required: 'Please provide some content as it pertains to your inquiry'
},
"CONTACT": {
required: "Please enter a contact person or company"
},
hiddenRecaptcha: {
required: function() {
$(".g-recaptcha:first").tooltip("enable").tooltip("show");
}
}
},
showErrors: function(errorMap, errorList) {
// Clean up any tooltips for valid elements
$.each(this.validElements(), function (index, element) {
element = $(element);
NoError_ToolTip(element);
});
// Create new tooltips for invalid elements
$.each(errorList, function (index, error) {
element = $(error.element);
message = error.message;
Error_ToolTip(element,message);
});
},
invalidHandler: function (event, validator) { //display error alert on form submit
success.hide();
$(document).scrollTop( $(".form-body").offset().top );
},
submitHandler: function () {
Submit_Complete();
}
});
function Submit_Complete(){
var obj = form.serializeObject();
console.log(obj);
$(".g-recaptcha:first").tooltip("disable").tooltip("hide");
$('.shell').html('<div class="loading"><span class="caption">Sending...</span><img src="/images/loading.gif" alt="loading"></div>');
$.ajax({
type: "POST",
url: "http://www.domain.com:8082/rest/RPGPGM2?callback=?",
data: obj,
//contentType: "application/json; charset=utf-8",
dataType: "jsonp"}).
done(function(data){
$(".shell").html('<label class="msg xs-small">' + data["MESSAGE"] + '</label><br><br><br><br><br><br><br><br><br>'+
'<div class="caption right">'+
'<a href="index.php" id="defaultActionButton" class="btn green">Home <i class="fa fa-home"></i></a>'+
'</div>');
}).
fail(function(){
$(".shell").html("<label class='msg xs-small'>We're Sorry!<br><br><br><br><span class='text-danger'>Unfortunately this inquiry cannot be processed at this time." +
"<br>Please try again at a later time or give us a call at:</span><br><br>+1.800.406.1291</label><br><br><br><br><br><br><br><br><br>"+
'<div class="caption right">'+
'<a href="index.php" id="defaultActionButton" class="btn green">Home <i class="fa fa-home"></i></a>'+
'</div>');
});
}
}
/**
* 序列化表格 data/objects。这实际上创建了一个我们的 CGIAPI 能够处理的 javascript 对象!
*
*/
$.fn.serializeObject = function() {
var o = {};
var a = this.serializeArray();
var $value = '';
$.each(a, function() {
if (o[this.name]) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
</script>
我们可以通过使用某种类型的 CGI API(例如 QtmhRdStin
或通过创建 Web 服务来进行 RESTful 调用。本方案属于前者。
这是基本 CGI 的列表 APIs:
RPGLE PGM:
// $Incoming: Test and load the incoming parameters
Begsr $Incoming;
cgiPostToGet(); // Convert POST to GET
callback = cgiParseGet('callback'); // never delete - unique key for the request
p#UserID = cgiParseGet('USER');
if (%scan(#lf:p#UserID) <> 0);
p#UserID = *blanks;
endif;
p#Instance = cgiParseGet('INSTANCE');
if (%scan(#lf:p#Instance) <> 0);
p#Instance = *blanks;
endif;
p#Function = cgiParseGet('FUNCTION');
p#Contact = cgiParseGet('CONTACT');
if (%scan(#lf:p#Contact) <> 0);
p#Contact = *blanks;
endif;
p#Email = cgiParseGet('EMAIL');
p#Msg = cgiParseGet('MSG');
p#Related = cgiParseGet('TYPE');
exsr $InzSr;
Endsr;
Begsr $Outgoing;
// Tell Consumer that a JSON string will be sent
ajx_data = 'Content-type: text/javascript' + CRLF + CRLF; // DO NOT CHANGE THIS LINE!!!
QtmhWrStout(ajx_data: %len(%trimr(ajx_data)): ajx_err);// DO NOT CHANGE THIS LINE!!!
ajx_data = %trim(callback) + '(' + %char(LBrace); // DO NOT CHANGE THIS LINE!!!
QtmhWrStout(ajx_data: %len(%trimr(ajx_data)): ajx_err);// DO NOT CHANGE THIS LINE!!!
ajx_data = '"MESSAGE":"' + %trim(p#message) + '"';
QtmhWrStout(ajx_data: %len(%trimr(ajx_data)): ajx_err);
// load the final right brace to complete the JSON string
ajx_data = %char(RBrace) + ');'; // DO NOT CHANGE THIS LINE!!!
QtmhWrStout(ajx_data: %len(%trimr(ajx_data)): ajx_err); // DO NOT CHANGE THIS LINE!!!
Endsr;
****注意****
如果我们不能直接序列化我们的表单,我们必须像这样构建一个 javascript 对象:
var obj = {USER : localProfile,
INSTANCE : "HTHACKNEY",
PAGE : $('select[name="PAGE"]').val(),
TITLE : $("input[name='TITLE']").val(),
HTML : html,
STARTDATE : $("input[name='STARTDATE']").val(),
ENDDATE : $("input[name='ENDDATE']").val(),
ARCHIVE : $("input[name='ARCHIVE']").val(),
ACTIVE : $("input[name='ACTIVE']").val(),
URGENT : $("input[name='URGENT']").val(),
AUTHLST : authStr};
$.ajax({
type: "POST",
url: "http://webservices.hthackney.com/web054S?callback=?",
data: data,
dataType:'jsonp'
}).done({ //do something on success });
不幸的是,您可以 POST
使用 JSONP
但您无法阅读 header 响应。
我终于找到了在单个域上同时执行 db2
和 ajax
请求的解决方案。
这里的解决方案
如果您需要在 IBMi 环境中对 SAME DOMAIN 执行 AJAX 请求 w/apache/PASE 您需要以下 ScriptAlias
和 [= 中的两个指令46=] 文件:
ScriptAliasMatch /rest/([0-9a-zA-Z]+$) /qsys.lib/rest.lib/.pgm
<Directory /qsys.lib/obj.lib/>
order allow,deny
allow from all
Header Always Set Access-Control-Allow-Origin *
Options +ExecCGI +Includes -Indexes +MultiViews
CGIConvMode %%MIXED/MIXED%%
</Directory>
<Directory /qsys.lib/rest.lib>
CGIConvMode %%EBCDIC/EBCDIC%%
Order Allow,Deny
Allow From all
Header Always Set Access-Control-Allow-Origin *
Options +ExecCGI -FollowSymLinks -SymLinksIfOwnerMatch +Includes -IncludesNoExec -Indexes -MultiViews
</Directory>
rest.lib 成员是所有 ajax rpgle pgms 所在的地方。
obj.lib 是 PHP
中 db2
调用的所有 CALL WEBXXX
所在的位置。
现在您可以在 /rest/PGM
模式下调用 AJAX 请求。
例如:
$.ajax({
type: "POST",
url: "http://www.domain.com/rest/WEB055S",
data: obj,
contentType: "application/json; charset=utf-8"
).
done(function(data){
$("#signupForm .loading").addClass("hidden");
//Successful Submit!
if(typeof data.MESSAGE != "undefined"){
clicked = 0;
$("#ok_msg").html(data.MESSAGE).show();
}
else{//ERROR
//console.log(data.ERROR);
$("#attendee #hth_err_msg").html(data.ERROR).show();
$('.add-attendee').addClass('hidden');
$('.edit-attendee').addClass('hidden');
}
}).
fail(function(){
$("#hth_err_msg").html("We're sorry, you're request cannot be processed at this time. It is likely the corporate system is under maintenance.").show();
});
您可以使用什么 CGI API 将 $.getJSON()
替换为 $(ajax)...POST
。在 IBM i 环境中使用 CGIDEV2 时,GET
用于所有内容(即:GET, PUT, POST, DELETE
)?我不想以传统方式传递我的参数,例如:$('[name="EMAIL"]').val()
而我想传递 JSON 对象字符串,例如:{"form" : [{ "email": "yardpenalty@yahoo.com"}]}
。
我们可以使用 CGIDEV2 使用 $.getJSON()
执行 PostToGet 回调,但我不能完全使用 $.ajax
。这是我们现在所做的,即所有 GET
个请求
PHP/JS:
// load all parameters
data = 'INSTANCE=<?echo trim($PATH_INSTANCE)?>' +
'&FUNCTION=<?echo urlencode(trim($FUNCTIONCODE))?>' +
'&USER=' + $('[name="USER"]').val() +
'&CONTACT=' + w$('[name="CONTACT"]').val() +
'&EMAIL=' + $("input[name='EMAIL']").val() +
'&MSG=' + $('[name="MSG"]').val() +
'&TYPE=' + $('[name="TYPE"]').val();
// Call the RPG REST JSONP program
$.getJSON( "http://www.domain.com:8082/rest/RPGLEPGM?callback=?",data )
.done(function( json ) { ... }
//Domain is actually
http://www.domain.com:8081
RPGLE PGM:
Begsr $Incoming;
cgiPostToGet(); // Convert POST to GET
callback = cgiParseGet('callback'); // callback
p#Function = cgiParseGet('FUNCTION');
Endsr;
但我希望能够使用其他 AJAX 方法执行各种操作,例如简单地即时更新记录 .post()/.ajax()
或简单的 .get()
ajax 调用无需创建回调。我不想每次使用 ajax 时都必须使用 getJSON 更不用说它在 GET 上对 POST 的不良做法,但据我了解 .getJSON()
提供 JSONP 功能,而其他默认情况下不提供。
编辑: 我们确实有我们的 ajax RPGLE PGMS 在与实际网站不同的端口所以 JSONP 是必要的并且客户知道它JSONP 因为我们将 callback
函数传回。
因为我们的 ajax RPGLE PGM CALLS 与 PHP 请求在不同的端口(想想主机服务器上的不同域),这符合跨域请求;因此,我们必须使用 JSONP(如果存在安全问题,则使用 Cors)将 &callback=?
function/wrapper 传回客户端。我在 SO 上的 JSONP 上找到了一篇非常好的文章,这正是这个 ajax 调用正在使用的内容。
RPGLE jQuery ajax 请求可以通过使用某种 CGI API 在您的 OS/400 - IBM i Web 环境中访问。当使用 ajax 调用(CALLB
或 CALLP
)一个 RPGLE PGM 时,我们实际上是在进行程序调用,但是当使用全局温度时,我们实际上是在进行 SQL 程序调用,它就资源而言更昂贵,这就是 Web 服务变得越来越流行的原因。
不仅根据请求从表单数据传递 javascript 对象,而且通过 Ajax 请求传递 return JSON 对象比存储全局临时数据更实用在 db2 环境中并将其处理为响应中的 PHP 数组。
通过在客户端处理 JSON 字符串,而不是同时使用服务器内存和驱动器 space 以及 PHP 数组和全局临时文件所需的磁盘 read/writes,我们真正能够利用更现代的网页设计实践。
这是一个在不使用 $.getJSON()
的情况下正确使用 $.ajax
/PHP/RPGLE 的工作示例:
<script>
$(document).ready(function(){
GetEmail("#email", '<?php echo trim($USER)?>', '<?php echo $PATH_INSTANCE?>');
FormValidation();
});
function FormValidation(){
//Variables created without the keyword var, are always global, even if they are created inside a function.
var form = $('#<?echo $PAGEID?>');
var FormError = $('.alert-danger',form);
var success = $('.alert-success',form);
form.validate({
focusInvalid: false, // do not focus the last invalid input
onkeyup: false,
ignore: ".ignore", //required for hidden input validation ie: hiddenRecaptcha
rules:{
"TYPE": {
required: true,
},
"MSG": {
required: true,
rangelength:[40,1000]
},
"CONTACT": {
required: {
depends: "#newuser:checked"
}
},
"EMAIL": {
required: true,
email: {
depends: function() {
if(!$("#newuser:checked"))
return true;
else
return false;
}
},
HTH_TelephoneEmail: {
depends: function() {
if($("#newuser:checked"))
return true;
else
return false;
}
}
},
hiddenRecaptcha: {
required: function () {
if (grecaptcha.getResponse() == '') {
return true;
} else {
return false;
}
}
}
},
messages: { // custom messages for form validation input
"TYPE": {
required: 'Please select an option as it pertains to your inquiry'
},
"MSG": {
required: 'Please provide some content as it pertains to your inquiry'
},
"CONTACT": {
required: "Please enter a contact person or company"
},
hiddenRecaptcha: {
required: function() {
$(".g-recaptcha:first").tooltip("enable").tooltip("show");
}
}
},
showErrors: function(errorMap, errorList) {
// Clean up any tooltips for valid elements
$.each(this.validElements(), function (index, element) {
element = $(element);
NoError_ToolTip(element);
});
// Create new tooltips for invalid elements
$.each(errorList, function (index, error) {
element = $(error.element);
message = error.message;
Error_ToolTip(element,message);
});
},
invalidHandler: function (event, validator) { //display error alert on form submit
success.hide();
$(document).scrollTop( $(".form-body").offset().top );
},
submitHandler: function () {
Submit_Complete();
}
});
function Submit_Complete(){
var obj = form.serializeObject();
console.log(obj);
$(".g-recaptcha:first").tooltip("disable").tooltip("hide");
$('.shell').html('<div class="loading"><span class="caption">Sending...</span><img src="/images/loading.gif" alt="loading"></div>');
$.ajax({
type: "POST",
url: "http://www.domain.com:8082/rest/RPGPGM2?callback=?",
data: obj,
//contentType: "application/json; charset=utf-8",
dataType: "jsonp"}).
done(function(data){
$(".shell").html('<label class="msg xs-small">' + data["MESSAGE"] + '</label><br><br><br><br><br><br><br><br><br>'+
'<div class="caption right">'+
'<a href="index.php" id="defaultActionButton" class="btn green">Home <i class="fa fa-home"></i></a>'+
'</div>');
}).
fail(function(){
$(".shell").html("<label class='msg xs-small'>We're Sorry!<br><br><br><br><span class='text-danger'>Unfortunately this inquiry cannot be processed at this time." +
"<br>Please try again at a later time or give us a call at:</span><br><br>+1.800.406.1291</label><br><br><br><br><br><br><br><br><br>"+
'<div class="caption right">'+
'<a href="index.php" id="defaultActionButton" class="btn green">Home <i class="fa fa-home"></i></a>'+
'</div>');
});
}
}
/** * 序列化表格 data/objects。这实际上创建了一个我们的 CGIAPI 能够处理的 javascript 对象! * */
$.fn.serializeObject = function() {
var o = {};
var a = this.serializeArray();
var $value = '';
$.each(a, function() {
if (o[this.name]) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
</script>
我们可以通过使用某种类型的 CGI API(例如 QtmhRdStin
或通过创建 Web 服务来进行 RESTful 调用。本方案属于前者。
这是基本 CGI 的列表 APIs:
RPGLE PGM:
// $Incoming: Test and load the incoming parameters
Begsr $Incoming;
cgiPostToGet(); // Convert POST to GET
callback = cgiParseGet('callback'); // never delete - unique key for the request
p#UserID = cgiParseGet('USER');
if (%scan(#lf:p#UserID) <> 0);
p#UserID = *blanks;
endif;
p#Instance = cgiParseGet('INSTANCE');
if (%scan(#lf:p#Instance) <> 0);
p#Instance = *blanks;
endif;
p#Function = cgiParseGet('FUNCTION');
p#Contact = cgiParseGet('CONTACT');
if (%scan(#lf:p#Contact) <> 0);
p#Contact = *blanks;
endif;
p#Email = cgiParseGet('EMAIL');
p#Msg = cgiParseGet('MSG');
p#Related = cgiParseGet('TYPE');
exsr $InzSr;
Endsr;
Begsr $Outgoing;
// Tell Consumer that a JSON string will be sent
ajx_data = 'Content-type: text/javascript' + CRLF + CRLF; // DO NOT CHANGE THIS LINE!!!
QtmhWrStout(ajx_data: %len(%trimr(ajx_data)): ajx_err);// DO NOT CHANGE THIS LINE!!!
ajx_data = %trim(callback) + '(' + %char(LBrace); // DO NOT CHANGE THIS LINE!!!
QtmhWrStout(ajx_data: %len(%trimr(ajx_data)): ajx_err);// DO NOT CHANGE THIS LINE!!!
ajx_data = '"MESSAGE":"' + %trim(p#message) + '"';
QtmhWrStout(ajx_data: %len(%trimr(ajx_data)): ajx_err);
// load the final right brace to complete the JSON string
ajx_data = %char(RBrace) + ');'; // DO NOT CHANGE THIS LINE!!!
QtmhWrStout(ajx_data: %len(%trimr(ajx_data)): ajx_err); // DO NOT CHANGE THIS LINE!!!
Endsr;
****注意****
如果我们不能直接序列化我们的表单,我们必须像这样构建一个 javascript 对象:
var obj = {USER : localProfile,
INSTANCE : "HTHACKNEY",
PAGE : $('select[name="PAGE"]').val(),
TITLE : $("input[name='TITLE']").val(),
HTML : html,
STARTDATE : $("input[name='STARTDATE']").val(),
ENDDATE : $("input[name='ENDDATE']").val(),
ARCHIVE : $("input[name='ARCHIVE']").val(),
ACTIVE : $("input[name='ACTIVE']").val(),
URGENT : $("input[name='URGENT']").val(),
AUTHLST : authStr};
$.ajax({
type: "POST",
url: "http://webservices.hthackney.com/web054S?callback=?",
data: data,
dataType:'jsonp'
}).done({ //do something on success });
不幸的是,您可以 POST
使用 JSONP
但您无法阅读 header 响应。
我终于找到了在单个域上同时执行 db2
和 ajax
请求的解决方案。
这里的解决方案
如果您需要在 IBMi 环境中对 SAME DOMAIN 执行 AJAX 请求 w/apache/PASE 您需要以下 ScriptAlias
和 [= 中的两个指令46=] 文件:
ScriptAliasMatch /rest/([0-9a-zA-Z]+$) /qsys.lib/rest.lib/.pgm
<Directory /qsys.lib/obj.lib/>
order allow,deny
allow from all
Header Always Set Access-Control-Allow-Origin *
Options +ExecCGI +Includes -Indexes +MultiViews
CGIConvMode %%MIXED/MIXED%%
</Directory>
<Directory /qsys.lib/rest.lib>
CGIConvMode %%EBCDIC/EBCDIC%%
Order Allow,Deny
Allow From all
Header Always Set Access-Control-Allow-Origin *
Options +ExecCGI -FollowSymLinks -SymLinksIfOwnerMatch +Includes -IncludesNoExec -Indexes -MultiViews
</Directory>
rest.lib 成员是所有 ajax rpgle pgms 所在的地方。
obj.lib 是 PHP
中 db2
调用的所有 CALL WEBXXX
所在的位置。
现在您可以在 /rest/PGM
模式下调用 AJAX 请求。
例如:
$.ajax({
type: "POST",
url: "http://www.domain.com/rest/WEB055S",
data: obj,
contentType: "application/json; charset=utf-8"
).
done(function(data){
$("#signupForm .loading").addClass("hidden");
//Successful Submit!
if(typeof data.MESSAGE != "undefined"){
clicked = 0;
$("#ok_msg").html(data.MESSAGE).show();
}
else{//ERROR
//console.log(data.ERROR);
$("#attendee #hth_err_msg").html(data.ERROR).show();
$('.add-attendee').addClass('hidden');
$('.edit-attendee').addClass('hidden');
}
}).
fail(function(){
$("#hth_err_msg").html("We're sorry, you're request cannot be processed at this time. It is likely the corporate system is under maintenance.").show();
});