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);
关键说明
- HTTP响应限制:单个请求只能返回一种响应,通过前端分开触发下载请求和跳转操作,绕开了这个限制。
- 会话存储BLOB:将获取到的PDF BLOB存在页面项中,确保下载流程能读取到对应内容。
- 延迟跳转:设置短暂延迟是为了保证浏览器有足够时间发起下载请求,避免跳转过快导致下载被取消。
内容的提问来源于stack exchange,提问作者Arif Sher Khan
相关产品推荐
相关产品推荐

