使用ORDS REST API从Oracle APEX传输BLOB至远程库时文件损坏
问题:Oracle APEX通过ORDS传输文件后BLOB损坏
在Oracle APEX中通过「文件浏览」项选择图片/文档后,调用ORDS POST API传输至远程数据库,文件存入远程库后BLOB出现损坏。
现有实现细节
1. APEX页面文件项配置

文件上传后会自动存入APEX临时表apex_application_temp_files。
2. 前端上传按钮JS代码
点击「上传」按钮时执行以下JavaScript逻辑:
var fileName = $v('P28_NEW'); var getImageDetails = async function() { return apex.server.process( "GET_IMAGE_DETAILS", { x01: fileName }, { async: false, dataType: "json", success: function(pData) { console.log('success'); console.log('requestBody:'+JSON.stringify(pData)); }, error: function(request, status, error) { alert("Error1:" + error); }, } ); }; async function mainFunction() { try { var callFunction1 = await getImageDetails(); var apiUrl = '...../ords/..../..../image/api?TITLE=test&FILENAME=test&SUBMITTED_BY=ssss&MIMETYPE=application/pdf'; var imageContent = callFunction1.image; var imageType = callFunction1.mimetype; fetch(apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: imageContent }) .then(function(response) { if (response.ok) { console.log('successful'); } else { console.error('failed'); } }) .catch(function(error) { console.error('Error:', error); }); } catch (e) { console.error(e); } } mainFunction();
3. AJAX调用的PL/SQL过程(GET_IMAGE_DETAILS)
该过程从临时表提取文件内容并返回:
DECLARE l_image CLOB; l_mime_type VARCHAR2 (255); l_imag1e varchar2(500):= APEX_APPLICATION.g_x01; BEGIN SELECT blob_content, mime_type INTO l_image, l_mime_type FROM apex_application_temp_files WHERE name = l_imag1e; apex_json.open_object; apex_json.write('image', l_image); apex_json.write('mimetype', l_mime_type); apex_json.close_object; EXCEPTION WHEN OTHERS THEN apex_json.open_object; apex_json.write('message', sqlerrm); apex_json.close_object; END;
4. 远程ORDS REST API配置
远程API通过:body参数提取请求内容:
问题原因及修复方案
核心问题
- BLOB直接转CLOB导致数据损坏:PL/SQL中直接将
blob_content(二进制类型)赋值给CLOB变量,会因字符编码不匹配破坏二进制结构。 - 二进制数据未编码直接JSON传输:JSON无法原生处理二进制内容,直接传输会导致部分字节被错误解析。
- 请求Content-Type设置错误:传输二进制文件时使用
application/json类型,不符合文件传输的规范。
修复步骤
步骤1:修改PL/SQL过程,将BLOB转为Base64编码字符串
DECLARE l_image_base64 VARCHAR2(32767); -- 大文件需改用CLOB配合DBMS_LOB处理 l_mime_type VARCHAR2(255); l_filename VARCHAR2(500) := APEX_APPLICATION.g_x01; l_blob BLOB; BEGIN SELECT blob_content, mime_type INTO l_blob, l_mime_type FROM apex_application_temp_files WHERE name = l_filename; -- 将BLOB转为Base64编码,避免二进制传输丢失 l_image_base64 := UTL_ENCODE.base64_encode(l_blob); apex_json.open_object; apex_json.write('image', l_image_base64); apex_json.write('mimetype', l_mime_type); apex_json.close_object; EXCEPTION WHEN OTHERS THEN apex_json.open_object; apex_json.write('message', SQLERRM); apex_json.close_object; END;
步骤2:修改前端JS,正确解码Base64并使用FormData传输
var fileName = $v('P28_NEW'); var getImageDetails = async function() { return apex.server.process( "GET_IMAGE_DETAILS", { x01: fileName }, { dataType: "json", error: function(request, status, error) { alert("获取文件详情失败:" + error); }, } ); }; async function mainFunction() { try { var fileData = await getImageDetails(); if (fileData.message) { console.error(fileData.message); return; } // 构造FormData,适配文件传输规范 var formData = new FormData(); formData.append('file', atob(fileData.image), fileName); formData.append('mimetype', fileData.mimetype); formData.append('TITLE', 'test'); formData.append('SUBMITTED_BY', 'ssss'); var apiUrl = '...../ords/..../..../image/api'; fetch(apiUrl, { method: 'POST', body: formData // 无需手动设置Content-Type,浏览器会自动添加multipart/form-data及边界 }) .then(function(response) { if (response.ok) { console.log('文件上传成功'); } else { console.error('文件上传失败'); } }) .catch(function(error) { console.error('请求错误:', error); }); } catch (e) { console.error(e); } } mainFunction();
步骤3:修改远程ORDS API处理逻辑
如果使用FormData传输,ORDS会自动解析参数,可直接提取BLOB:
DECLARE l_blob BLOB; BEGIN -- 从FormData中获取文件BLOB和参数 l_blob := :file; INSERT INTO your_target_table (blob_column, mime_type, filename, title, submitted_by) VALUES (l_blob, :mimetype, :filename, :TITLE, :SUBMITTED_BY); COMMIT; END;
如果仍需使用JSON传输,可在远程API中将Base64字符串解码回BLOB:l_blob := UTL_ENCODE.base64_decode(UTL_RAW.cast_to_raw(:body.image));
内容的提问来源于stack exchange,提问作者Shivdutt
相关产品推荐
相关产品推荐

