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 调用(CALLBCALLP)一个 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&nbsp;<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&nbsp;<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 响应。

我终于找到了在单个域上同时执行 db2ajax 请求的解决方案。

这里的解决方案

如果您需要在 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.libPHPdb2 调用的所有 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();
       });