如何在Oracle Apex中调用外部API?

问题描述 投票:0回答:1

我遇到以下问题:

我在 Oracle APEX 中有一个应用程序,当我单击按钮时,我需要调用外部 API。

我想到的解决方案是在按钮上创建一个动态操作,单击时执行 JavaScript 代码(代码如下)。

但是当代码执行时,我在控制台中收到以下错误:

从源“http://minha-url.com.br”获取“https://api.rd.services/platform/events?event_type=sale”的访问已被 CORS 策略阻止:对预检的响应请求未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。如果不透明响应满足您的需求,请将请求模式设置为“no-cors”以在禁用 CORS 的情况下获取资源。

我的代码:

let options = {
  method: 'POST',
  headers: {
    accept: 'application/json',
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${accessToken}`,
  },
  body: JSON.stringify({
    event_type: 'SALE',
    event_family: 'CDP',
    payload: {
      email: '[email protected]',
      funnel_name: 'default',
      value: 999
    }
  })
};

fetch('https://api.rd.services/platform/events?event_type=sale', options)
  .then(response => response.json())
  .then(response => console.log(response))
  .catch(err => console.error(err));

我查阅了API文档,其中包含以下信息:

使用 access_token 授权请求的 RD Station 营销 API 仅允许来自应用程序后端的请求。这是因为此 API 中使用的令牌无法在浏览器中公开,因为它允许访问有关您帐户中联系人的私人信息。

如何使用 CORS 解决此错误?

单击按钮时我需要向外部 API 发出 POST 请求。

javascript oracle plsql oracle-apex
1个回答
0
投票

他们的 API 文档很好地解释了 CORS 问题:你无法从客户端浏览器使用 javascript 调用他们的 API;你必须从你的服务器调用他们的 API。

您没有一种简单的方法来解决 CORS - API 告诉浏览器不允许它来自您的站点,并且浏览器同意。这些都不是你能控制的。

您可以做的是从 PL/SQL 调用他们的 API。 API 请求将来自您的数据库服务器,而不是来自客户端的浏览器,因此 CORS 不适用。正如他们的文档指出的那样,敏感的访问令牌只会从您的服务器传递到 API,因此您的客户端无法窃取它。

您最简单的选择可能是APEX_WEB_SERVICE.make_rest_request

首先需要创建ACL以允许数据库访问远程Web服务器。作为系统或管理员帐户运行:

declare
  l_principal VARCHAR2(20) := 'APEX_190200'; -- this should match your APEX schema name
  l_host varchar2(100) := 'api.rd.services'; -- remote server name
begin
  dbms_network_acl_admin.create_acl (
    acl          => 'my_acl.xml',
    description  => 'my acl',
    principal    => l_principal,
    is_grant     => TRUE,
    privilege    => 'connect',
    start_date   => systimestamp,  
    end_date     => null);
  dbms_network_acl_admin.assign_acl (
    acl         => 'my_acl.xml',
    host        => l_host, 
    lower_port  => 443,
    upper_port  => 443); 
  commit;
end;
/

然后你可以在 APEX 中使用这样的块:

declare
  l_clob clob;
  l_access_token varchar2(100) := 'io7u34907iafh394897';
begin
  apex_web_service.set_request_headers(
      p_name_01        => 'Content-Type',
      p_value_01       => 'application/json',
      p_name_02        => 'Authorization',
      p_value_02       => 'Bearer ' || l_access_token,
      p_reset          => false,
      p_skip_if_exists => true );
  l_clob := apex_web_service.make_rest_request(
    p_url         => 'https://api.rd.services/platform/events?event_type=sale',
    p_http_method => 'POST',
    p_body => '{
  event_type: ''SALE'',
  event_family: ''CDP'',
  payload: {
    email: ''[email protected]'',
    funnel_name: ''default'',
    value: 999
  }
}'
  ) ;
  :P101_RESULT := l_clob;
end;

在此示例中,访问令牌被硬编码在 PL/SQL 块中,但您也可以将其存储在应用程序项变量中。您可能不希望将其存储在最终用户可以在 HTML 中看到的页面项中。

本例中的 API 结果存储在页面项 P101_RESULT 中。您可能想将其存储在其他地方。

Oracle-Base 站点上也有 这样的示例

© www.soinside.com 2019 - 2024. All rights reserved.