You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle Apex中调用REST API下载PDF后跳转页面的问题

解决方案:下载PDF后自动跳转回主页面

由于HTTP协议限制,单个请求只能返回一种响应(要么是文件下载,要么是页面跳转),因此需要通过前端JavaScript触发两个独立操作实现需求:先触发PDF下载,再跳回主页面。以下是具体实现步骤:

步骤1:修改跳转页面的Before Page Header流程

保留获取PDF的核心逻辑,移除直接输出下载的代码,改为将PDF的BLOB存储到会话页面项中:

修改后的PL/SQL代码

DECLARE
    lc_response     BLOB;
    l_blob          BLOB;
    l_url           varchar2(4000);
    lm_multipart    apex_web_service.t_multipart_parts;
    lc_json         CLOB := '[{
    "D1": 194645,
    "R1": 1,
    "R2": 9,
    "R3": 4,
    "R4": 6,
    "R5": 4,
    "R6": 5
    }]';
    lv_filename     VARCHAR2(20) := 'my_file.pdf';
    lv_base_url     VARCHAR2(100) := 'http://10.50.200.11:27005/report'; -- webservice base URL; 
    lb_blob         BLOB; -- Blob part of the multipart
    l_file_mimetype apex_application_files.mime_type%TYPE;
BEGIN
    -- 读取数据库中的PDF模板
    SELECT
        input_template
    INTO lb_blob
    FROM
        python_input_template
    WHERE
        sno = 1;

    -- 设置API请求头
    apex_web_service.set_request_headers(
                                        p_name_01  => 'x-api-key',
                                        p_value_01 => 'qwerty_key',
                                        p_name_02  => 'x-api-user',
                                        p_value_02 => 'APEX'
    );

    -- 添加JSON数据到多部分请求
    apex_web_service.append_to_multipart(
                                        p_multipart    => lm_multipart,
                                        p_name         => 'data_str',
                                        p_content_type => 'application/json',
                                        p_body         => lc_json
    );
    -- 添加PDF模板到多部分请求
    apex_web_service.append_to_multipart(
                                        p_multipart    => lm_multipart,
                                        p_name         => 'template',
                                        p_filename     => lv_filename,
                                        p_content_type => 'application/pdf',
                                        p_body_blob    => lb_blob
    );

    -- 调用REST API获取填充后的PDF
    lc_response := apex_web_service.make_rest_request_b(
                                                     p_url         => lv_base_url,
                                                     p_http_method => 'POST',
                                                     p_body_blob   => apex_web_service.generate_request_body(lm_multipart)
                   ); 

    -- 将PDF的BLOB存储到隐藏页面项(需提前创建P_DOWNLOAD_PDF,类型为BLOB)
    :P_DOWNLOAD_PDF := lc_response;
    -- 存储下载文件名(提前创建P_DOWNLOAD_FILENAME,类型为文本)
    :P_DOWNLOAD_FILENAME := 'l_file_name.pdf';
END;

步骤2:创建页面流程用于触发下载

在跳转页面中新增一个页面流程:

  • 流程类型:PL/SQL
  • 执行点:On Load - Before Header
  • 条件:请求等于 DOWNLOAD_PDF
  • PL/SQL代码:
BEGIN
    sys.htp.init;
    owa_util.mime_header(
                        'application/pdf',
                        false,
                        'UTF-8'
    );
    sys.htp.p('Content-Disposition: attachment; filename="'
              || :P_DOWNLOAD_FILENAME
              || '"');
    sys.htp.p('Content-length: '
              || sys.dbms_lob.getlength(:P_DOWNLOAD_PDF));

    sys.owa_util.http_header_close;
    wpg_docload.download_file(:P_DOWNLOAD_PDF);
    apex_application.stop_apex_engine;
END;

步骤3:添加JavaScript实现下载+跳转

在跳转页面的JavaScript > Function and Global Variable Declaration中添加以下代码:

function initDownloadAndRedirect() {
    // 构建下载请求URL
    const downloadUrl = apex.util.prepareUrl(
        'f?p=' + apex.app.g_instance + ':' + apex.page.pageId + ':' + apex.app.g_sessionId + '::NO:::REQUEST:DOWNLOAD_PDF'
    );
    // 触发PDF下载(用_blank打开避免阻塞跳转)
    window.open(downloadUrl, '_blank');
    
    // 延迟1秒跳转,确保下载请求已发起(可根据实际调整延迟时间)
    setTimeout(() => {
        const mainPageUrl = apex.util.prepareUrl(
            'f?p=' + apex.app.g_instance + ':6:' + apex.app.g_sessionId + '::NO:::'
        );
        window.location.href = mainPageUrl;
    }, 1000);
}

// 页面加载完成后自动执行
document.addEventListener('DOMContentLoaded', initDownloadAndRedirect);

关键说明

  1. HTTP响应限制:单个请求只能返回一种响应,通过前端分开触发下载请求和跳转操作,绕开了这个限制。
  2. 会话存储BLOB:将获取到的PDF BLOB存在页面项中,确保下载流程能读取到对应内容。
  3. 延迟跳转:设置短暂延迟是为了保证浏览器有足够时间发起下载请求,避免跳转过快导致下载被取消。

内容的提问来源于stack exchange,提问作者Arif Sher Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 21:55:09