RTC Forums
November 23, 2024, 09:28:59 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
 
   Home   Help Login Register  
Pages: [1]
  Print  
Author Topic: How to do JavaScript calls to the RTC server using XML-RPC  (Read 9359 times)
brian71us
RTC Expired
*
Posts: 15


« on: September 16, 2016, 04:07:28 PM »


I've built a simple server using Real Thin Client that has a couple of functions. I'd like to call these functions from a web page using the XML-RPC library below.

http://plugins.jquery.com/xmlrpc/

I have added the library to my web page as described and created a function (shown below) to make a request.

        function getUsers() {
            $.xmlrpc({
               url: 'http://localhost:8095/mytest',
               methodName: 'GetData',
               params: [{Table: 'BrechbuhlerUser'}],
               success: function(response, status, jqXHR) { document.getElementById("theResponse").innerHTML = response; },
               error: function(jqXHR, status, error) { document.getElementById("theResponse").innerHTML = error; }
            });

The server is listening on port 8095 and I have TRtcServerModule with the module file name 'mytest', a function group, and two functions (one named GetData).

The function's event handler is shown below.

procedure TDataModule1.RtcFunction2Execute(Sender: TRtcConnection;
  Param: TRtcFunctionInfo; Result: TRtcValue);
var
  ja: TJSONArray;
  results: string;
begin
  with Sender as TRtcDataServer do
  begin
    results := '';

    query.SQL.Text := 'SELECT * FROM [' + Param.asString['Table'] + ']';

    try
      query.Open;

      ja := TConverter.New.DataSet(query).AsJSONArray;

      results := ja.ToJSON;
    finally
      Result.asString := results;

      query.Close;
    end;
  end;
end;

Is this everything that I need to do? Am I missing a step?
Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #1 on: September 16, 2016, 08:07:35 PM »

Since you are using XML-RPC, you have to enable XML-RPC format on the TRtcServerModule component by opening the DataFormats list in the object inspector and setting fmt_XMLRPC to True, because only fmt_RTC is enabled by default. Provided your TRtcServerModule is also attached to the Server (using its Server or Link property), your remote functions should become accessible using XML-RPC from any HTTP-based Client and you should be able to access all the parameters in the OnExecute event of your TRtcFunction component.

Here is an old FAQ topic about the translation between XML-RPC and RTC objects.

Best Regards,
Danijel Tkalcec
Logged
brian71us
RTC Expired
*
Posts: 15


« Reply #2 on: September 18, 2016, 01:58:46 AM »

OK, so everything works if I launch the web page from Chrome and serve up the pages from the built in web server.  Grin

If I double click the index.html file (or run it from within Brackets) then the web page opens but the XML-RPC call fails with the message "XMLHttpRequest cannot load http://localhost:8095/mytest. Response for preflight has invalid HTTP status code 404"  Huh

I have added the CORS header when the request is accepted by the web server component.

Any suggestions for how to troubleshoot this issue?
Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #3 on: September 19, 2016, 09:19:24 PM »

1. Are you using absolute URLs inside your HTML and JavaScript files to ensure that your Server will be receiving the request even if the HTML is served locally?

2. To check if your Server is receiving anything (regardless of context or source), you can add a new TRtcDataProvider component to your Project, set its CheckOrder property to -1 (it has to be lower than any other components CheckOrder value), assign your TRtcHttpServer component to its Server property and implement its OnCheckRequest event, from where you can log the following info:
-> TRtcDataServer(Sender).Request.HeaderText;
-> TRtcDataServer(Sender).Request.URL;

Or run your Server from Delphi in DEBUG mode and set a breakpoint in any OnCheckRequest event, then open the index.html file and see if anything happens on the Server side.

Best Regards,
Danijel Tkalcec
Logged
brian71us
RTC Expired
*
Posts: 15


« Reply #4 on: September 21, 2016, 07:32:58 PM »


This is the XML-RPC call in JavaScript:


        function getUsers() {
            $.xmlrpc({
               url: 'http://localhost:8095/mytest',
               methodName: 'GetData',
               params: [{Table: 'BrechbuhlerUser'}],
               success: function(response, status, jqXHR) { document.getElementById("theResponse").innerHTML = response; },
               error: function(jqXHR, status, error) { document.getElementById("theResponse").innerHTML = error; }
            });

The URL is absolute - http://localhost:8095/mytest


Here's what I get when I request the web page by opening the browser and entering http://localhost:8095/

localhost:8095/
Host: localhost:8095
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
COOKIE: ScaleDealer_DetailView_Main_Tabs=1; SupportTicket_DetailView_Main_SizeableEditors_Item2=0; Branch_DetailView_Main_Tabs=0

localhost:8095/jquery-1.9.1.min.js
Host: localhost:8095
Connection: keep-alive
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36
Accept: */*
Referer: http://localhost:8095/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
COOKIE: ScaleDealer_DetailView_Main_Tabs=1; SupportTicket_DetailView_Main_SizeableEditors_Item2=0; Branch_DetailView_Main_Tabs=0

localhost:8095/jquery.xmlrpc.js
Host: localhost:8095
Connection: keep-alive
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36
Accept: */*
Referer: http://localhost:8095/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
COOKIE: ScaleDealer_DetailView_Main_Tabs=1; SupportTicket_DetailView_Main_SizeableEditors_Item2=0; Branch_DetailView_Main_Tabs=0

localhost:8095/favicon.ico
Host: localhost:8095
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36
Accept: */*
Referer: http://localhost:8095/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
COOKIE: ScaleDealer_DetailView_Main_Tabs=1; SupportTicket_DetailView_Main_SizeableEditors_Item2=0; Branch_DetailView_Main_Tabs=0

localhost:8095/favicon.ico
Host: localhost:8095
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36
Accept: */*
Referer: http://localhost:8095/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
COOKIE: ScaleDealer_DetailView_Main_Tabs=1; SupportTicket_DetailView_Main_SizeableEditors_Item2=0; Branch_DetailView_Main_Tabs=0

localhost:8095/favicon.ico
Host: localhost:8095
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36
Accept: */*
Referer: http://localhost:8095/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
COOKIE: ScaleDealer_DetailView_Main_Tabs=1; SupportTicket_DetailView_Main_SizeableEditors_Item2=0; Branch_DetailView_Main_Tabs=0

localhost:8095/favicon.ico
Host: localhost:8095
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36
Accept: */*
Referer: http://localhost:8095/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
COOKIE: ScaleDealer_DetailView_Main_Tabs=1; SupportTicket_DetailView_Main_SizeableEditors_Item2=0; Branch_DetailView_Main_Tabs=0






This is what I get when I make the XML-RPC call when I enter "http://localhost:8095" in Chrome, which works properly...

localhost:8095/mytest
Host: localhost:8095
Connection: keep-alive
Content-Length: 194
Accept: application/xml, text/xml, */*; q=0.01
Origin: http://localhost:8095
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36
Content-Type: text/xml
Referer: http://localhost:8095/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
COOKIE: ScaleDealer_DetailView_Main_Tabs=1; SupportTicket_DetailView_Main_SizeableEditors_Item2=0; Branch_DetailView_Main_Tabs=0







If I double click "index.html" to open the web page instead of fetching it from the RTC web server...

localhost:8095/mytest
Host: localhost:8095
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: null
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36
Access-Control-Request-Headers: content-type
Accept: */*
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8




There is a difference, though why I don't know as I'm calling the same XML-RPC method whether I'm serving up the web page from RTC web server or double-clicking the index.html file.
Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #5 on: September 23, 2016, 11:57:51 AM »

When you get the HTML file from the Server, the JS library you are using will be sending a 'POST' request to the Server with the correct XML-RPC content in the request content body (as expected) and the OnExecute event will be triggered on the TRtcFunction component responsible for handling that specific XML-RPC request.

But ... if you open the same HTML file directly by double-clicking it in the File Explorer, instead of directly sending the "POST" request with the XML-RPC content, the Web Browser is sending an "OPTIONS" request to the Server, with no content body.

Since the TRtcServerModule component does NOT handle "OPTIONS" requests, you will have to add a "TRtcDataProvider" with a "CheckOrder" lower than that used by your TRtcServerModule component (for example: CheckOrder := -1) and implement its "OnCheckRequest" event to something like this:

procedure TForm1.OriginDataProviderCheckRequest(Sender: TRtcConnection);
var
  Srv:TRtcDataServer absolute Sender;
begin
if (Srv.Request.Method='OPTIONS') and (Srv.Request.FileName='/mytest') then
  begin
  Srv.Accept;
  Srv.Response['Access-Control-Allow-Headers']:='Origin, X-Requested-With, Content-Type, Accept';
  Srv.Response['Access-Control-Allow-Origin']:='*';
  Srv.Write;
  end;
end;

The above event will be ONLY handling "OPTIONS" requests for "/mytest" reuests. You might have to add more HTTP Response headers if you wat to handle other kinds of OPTIONS requests, but the above should do the trick for your specific problem with XML-RPC requests not being executed when the HTML file was loaded directly by double-clicking it in the File Explorer. If you want to make it general, you could also write a single Data Provider to handle all "OPTIONS" requests by removing the ...FileName='/mytest') check.

Best Regards,
Danijel Tkalcec
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.029 seconds with 16 queries.