cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

2024 Technology Preview Program:
Master powerful new features and shape the latest BIM-enabled innovations

Archicad C++ API
About Archicad add-on development using the C++ API.

Using the JSON interface from the browser

gcNamirial
Contributor

Hello,

i've created a set of commands that are registered in the addon so i can call them with the JSON interface and retrieve some data. I tried to use this logic with a Python script and it's working well.

 

Now i'm creating a dialog with a browser control. I managed to pass the data of the selection in the project to the browser and it's working fine.

The browser loads a page hosted in localhost so i can develop it using nodejs.

To develop without having to open the dialog everytime i'd like to get selection data from a command using the JSON interface. So i created a command that converts that data to JSON (GS::ObjectState) and returns that.

In the page, if the ACAPI functions are not present (when the page is not opened by the dialog but standalone in a browser) i try to fetch the data as in python, with javascript.

The issue is that the browser blocks the call because CORS policies. Archicad has 

http://localhost:19723 and the my page http://localhost:5173/ This is not an issue in python but usually the browser needs the server to have CORS headers to allow this if the addresses are different (different ports are considered so).
Any idea if it's possible to bypass this issue?

 

Thanks

4 REPLIES 4

Hi!
So you are hosting the webserver on localhost with nodejs correct?
I think there should be solutions to configure the nodejs webserver to accept specific addresses. (e.g. here: https://stackoverflow.com/questions/70060783/how-to-allow-cors-in-node-js). Or have you already try something like this?

 

Best,
Bernd

Bernd Schwarzenbacher - Archicad Add-On Developer - Get Add-Ons & Archicad Tips on my Website: Archi-XT.com

That configuration is useful when nodejs is the Web API server and the browser is fetching data from that. 

In my case the page is hosted by nodejs but it's a simple html page with javascript in it that send requests to another server (Archicad). In the end we will build all these files in a folder (to optimize the packages used) and add to the installation of the addon. The browser control in the dialog will access it from an url like "file://..." instead of localhost that is valid only when nodejs is running.

In the javascript i use the fetch API used usually by websites to interact with Web APIs. By default the browser follows the rule of the server itself, provided by the HTTP headers the server sends. 

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

In summary, the Archicad server would need to add 

Access-Control-Allow-Origin: *

to the headers so that any call from any place is allowed. If not the requests are denied if not from the same origin (same domain/port).

This check is done on the client side. In python usually that HTTP header is ignored, while browsers are more strict. It's possible to disable it by restarting the browser with disabled security but it's not ideal.

An option to make it work for now could be adding a python Web API server between the page and Archicad. The page sends the request to the python server (that has that CORS header to allow all), than this one asks the same thing to Archicad and send it back to the page. I run it in a terminal page when i develop the page and that's it.

It could be useful to have some settings for CORS to provide to Archicad so that it can add it to the data it returns, within the JSON interface. 

I see! Yeah a proxy server would be a possible solution. Another solution could be to use a browser extension that allows CORS for hostnames you specify. I think there are a few around but I haven't used or tested any.

(Side note: I was curious and did some digging in the AC installation. You can find a few files that are mentioning CORS settings in the GSCEF (probably stands for Graphisoft Chromium Embedded Framwork) subfolder. Maybe the mentioned settings (in CefSharp.xml) could be set in CefSharp.BrowserSubprocess.exe.config. But even then, that's probably not the setting for the JSON API Server but for Browsers embedded in Archicad.)

Bernd Schwarzenbacher - Archicad Add-On Developer - Get Add-Ons & Archicad Tips on my Website: Archi-XT.com

The .xml files seem class definitions for .net assembly files (the .dll files in that same folder). Usually they are created by Visual Studio when scanning the file. I guess they are provided by the library used by Archicad (CefSharp) that shows the browser in a dialog/panel.

Archicad can change the settings to the component but i don't think there's something visibile from C++ (in DG::Browser for example).

I've checked if there's a setting in CefSharp to disable security and there's one but it seems it has been removed in later versions 

https://github.com/cefsharp/CefSharp/commit/249c75a575944102735a29ff6526a4bf6710f342

Maybe they added another way to do that. 

About these settings that can be configured, there's another one it'd be useful to have. In my page i've an HTML canvas showing some graphics and the user can zoom these. When in the standalone browser it works at smooth framerate while in the addon dialog it's stuttering. 

It could be that hardware acceleration is disabled or the the framerate is limited. In some discussions they suggest to tweak that

BrowserSettings settings = new BrowserSettings();
settings.WindowlessFrameRate = 60;
settings.WebGl = CefState.Enabled;
ChromiumWebBrowser chrome_browser = new ChromiumWebBrowser(url)
{
    BrowserSettings = settings
};

These settings could be useful to be exposed in the C++ class, if you have more complex functionality in the page and want smooth rendering.