在页面对应的js文件中,我们可以编写发送请求的逻辑.
我们上传文件的逻辑:
document.getElementById('uploadBtn').onchange = function(event) { var file = event.target.files[0]; // 获取选择的文件 if (file) { var reader = new FileReader(); reader.onload = function(loadEvent) { var base64Image = loadEvent.target.result; // 显示图片预览 var previewImage = document.getElementById('previewImage'); previewImage.src = base64Image; previewImage.style.display = 'block'; // 确保图片显示 }; reader.onerror = function(error) { console.error('图像错误加载:', error); layui.layer.msg('图片加载失败'); }; reader.readAsDataURL(file); // 读取文件内容作为URL } };
这段代码实现在网页上上传图片并立即显示图片预览的功能。详细步骤如下:
-
获取元素和事件绑定:
使用
document.getElementById('uploadBtn')
选取页面中的文件上传按钮,这是一个类型为file
的输入元素。 为该元素添加一个
onchange
事件监听器,该监听器会在用户通过按钮选择文件后触发。 -
文件读取和处理:
当用户选择文件后,
onchange
事件被触发,事件处理函数从event.target.files
数组中获取第一个文件(files[0]
),这代表用户选中的文件。 检查获取到的文件是否存在。如果存在,继续执行读取操作;如果不存在,操作中断。
-
使用 FileReader 读取文件内容:
创建一个
FileReader
对象,这是HTML5提供的API,用于异步读取用户的文件内容。 定义onload事件的回调函数:当文件读取完成后,此函数被调用。在该函数内:
使用
loadEvent.target.result
获取文件的数据,此处得到的是一个base64编码的字符串,表示图片的内容。 获取页面上用于显示图片的
<img>
元素(previewImage
)。 将该
<img>
元素的src
属性设置为读取到的base64字符串,使图片在网页上显示。 设置图片元素的显示样式为
block
,确保图片元素是可见的。 -
错误处理:
定义
FileReader
的onerror
事件处理函数:如果在文件读取过程中发生错误,该函数将被调用。 在错误处理函数中,使用
console.error
将错误详细信息输出到浏览器的控制台,帮助调试和诊断问题。 同时,使用 Layui 框架的
layui.layer.msg
方法显示一个错误提示信息(“图片加载失败”),向用户反馈操作失败的状态。 -
启动文件读取:
使用
reader.readAsDataURL(file)
方法启动文件的读取。该方法将文件内容读取为一个能够直接被<img>
元素使用的URL格式(即base64编码的URL),完成从文件到图像预览的转换。
当我们在上传图片时,图片会显示在我们的上传页面上,用户看到要识别的图片。
用户提交请求函数:
document.getElementById('submitRequest').addEventListener('click', function() { var question = document.querySelector('input[name="question"]').value; var previewImage = document.getElementById('previewImage'); if (!previewImage.src || previewImage.src === "#") { layui.layer.msg('请先选择一张图片'); return; } var imageData = previewImage.src.replace(/^data:image\/[a-z]+;base64,/, ""); submitImage(imageData, question); });
这段JavaScript代码主要处理用户在一个网页表单中点击“提交请求”按钮的动作。具体包括:
-
收集用户输入的问题:获取页面中一个特定的输入框(名为
question
的输入框)里的值。 -
检查图片是否已上传:验证是否有图片已被加载到名为
previewImage
的<img>
标签中。如果没有图片或者图片的源地址是初始占位符("#"),则显示一个提示消息告诉用户需要先上传图片,并停止进一步操作。 -
处理和提交图片数据:
提取已上传图片的Base64编码内容。这通过移除图片数据URL的前缀部分来实现,只留下纯Base64编码的数据。
调用
submitImage
函数,并将提取的图片数据和用户的问题作为参数传递。这个函数可能负责进一步的数据处理或向服务器发送请求。
如下图所示:
获取图片理解事务id函数:
function submitImage(imageData, question) { fetch('/image-understanding/request', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({image: imageData, question: "请用中文回答我" + question}) }) .then(response => response.json()) .then(data => { if (data && data.result && data.result.task_id) { layui.layer.msg('请求已提交,正在获取结果...'); pollForResult(data.result.task_id); } else { layui.layer.msg('提交失败,没有返回任务ID,请稍后再试'); } }) .catch(error => { console.error('Error:', error); layui.layer.msg('请求错误,请检查控制台'); }); }
我们定义了一个名为 submitImage
的函数,它负责将用户上传的图片数据和关联的问题发送到服务器。大概包括:
-
发送HTTP请求:
使用
fetch
API 向服务器的/image-understanding/request
路径发起一个 POST 请求。这是一个异步操作,允许代码在等待响应时继续执行其他任务。请求的
headers
部分设置了Content-Type
为application/json
,表明发送的数据将是JSON格式。请求的
body
包含一个JSON字符串,这个字符串通过JSON.stringify
方法从一个对象转换而来,对象包括两个属性:image
(图片的Base64编码数据)和question
(拼接了固定中文前缀“请用中文回答我”和用户输入的问题字符串)。 -
处理响应:
fetch
请求返回的是一个Promise对象,这意味着你可以使用.then()
方法来处理当请求成功时返回的数据。第一个
.then()
调用确保从响应中解析出JSON格式的数据。第二个
.then()
处理这些数据:如果数据中包含result
和task_id
,显示一条消息“请求已提交,正在获取结果...”,并调用pollForResult
函数以轮询结果。如果没有task_id
,则显示“提交失败,没有返回任务ID,请稍后再试”。 -
错误处理:
使用
.catch()
捕捉请求过程中可能发生的任何错误,例如网络问题或服务器故障。如果捕获到错误,会在控制台输出错误详情,并通过界面显示“请求错误,请检查控制台”的消息提醒用户。
获取最终结果:
function pollForResult(taskId) { fetch('/image-understanding/get-result', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({task_id: taskId}) }) .then(response => response.json()) .then(data => { if (data.result.ret_msg === "processing") { console.log('结果解析中。。。'); setTimeout(() => pollForResult(taskId), 5000); } else if (data.result.ret_msg === "success") { translateDescription(data.result.description); } else { layui.layer.msg('获取结果失败,请稍后再试'); } }) .catch(error => { console.error('Error:', error); layui.layer.msg('获取结果错误,请检查控制台'); }); }
我们定义了一个名为 pollForResult
的函数,主要作用是轮询服务器以检查某项任务的处理结果。该函数通过发送POST请求到服务器,并根据服务器返回的状态执行不同的操作。具体步骤如下:
-
发送HTTP请求:
使用
fetch
API 向服务器的/image-understanding/get-result
路径发送一个 POST 请求,请求的目的是获取特定任务的处理结果。请求头
Content-Type
设置为application/json
,指明发送的数据格式。请求体包含一个JSON字符串,由
JSON.stringify
方法生成,其中包括一个属性task_id
,这是要查询结果的任务标识符。 -
处理服务器响应:
.then(response => response.json())
确保将服务器的响应转换为JSON格式。第二个 .then(data => {...}) 处理转换后的数据:
如果
data.result.ret_msg
的值为"processing"
,表示任务仍在处理中。此时,在控制台打印“结果解析中...”的消息,并使用setTimeout
延迟5秒后再次调用pollForResult(taskId)
函数,重新查询结果。如果
data.result.ret_msg
的值为"success"
,表示任务处理成功,并且处理结果可用。此时调用translateDescription(data.result.description)
函数,传递结果描述进行进一步的处理或显示。-
如果不是以上两种情况,则显示“获取结果失败,请稍后再试”的消息提醒用户。
-
-
错误处理:
.catch(error => {...})
捕获请求过程中发生的任何错误,例如网络问题或服务器异常。在控制台输出错误详情,并使用 Layui 框架的
layui.layer.msg
方法显示“获取结果错误,请检查控制台”的提示,以通知用户检查更详细的错误信息。
对结果进行翻译函数,因为原接口调用得到的结果是英文的,所以我们需要对英文结果进行翻译,翻译成中文。
function translateDescription(description) { fetch('/text', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify({description: description}) }) .then(response => { if (!response.ok) { throw new Error('响应失败'); } return response.json(); }) .then(data => { console.log('Received data:', data); // Debug: Log the received data if (data && data.result && data.result.trans_result && data.result.trans_result.length > 0) { const translatedText = data.result.trans_result[0].dst; displayResults(description, translatedText); } else { console.error('Translation failed, unexpected response structure:', data); layui.layer.msg('翻译失败,返回结构不正确,请检查后端输出'); } }) .catch(error => { console.error('Error:', error); layui.layer.msg('请求翻译服务失败,请检查控制台'); }); }
这段代码定义了一个名为 translateDescription
的函数,其主要目的是将给定的文本描述发送到服务器进行翻译,并处理翻译结果。以下是该函数的详细步骤和逻辑:
-
发起HTTP POST请求:
使用
fetch
API 向服务器的/text
路径发送一个 POST 请求,该请求旨在获取传入描述的翻译。设置请求头:
Content-Type: application/json
表明发送的数据将是 JSON 格式。Accept: application/json
指定期望从服务器接收 JSON 格式的响应。请求体中,使用
JSON.stringify({description: description})
将描述封装成 JSON 格式。 -
处理响应:
.then(response => {...})
首先检查响应是否成功(response.ok
)。如果响应状态不是成功的(即非2xx状态码),抛出错误。如果响应成功,调用
response.json()
将响应体转换为 JSON 对象。第二个 .then(data => {...}) 处理转换后的数据:
首先,打印接收到的数据以供调试。
检查返回的数据结构是否包含翻译结果。如果数据结构正确并包含至少一个翻译结果(
data.result.trans_result.length > 0
),提取翻译后的文本(data.result.trans_result[0].dst
),然后调用displayResults
函数,将原始描述和翻译后的文本显示出来。如果返回的数据结构不符合预期,输出错误到控制台,并显示错误消息提示翻译失败。
-
错误处理:
.catch(error => {...})
捕获请求过程中可能出现的任何错误,例如网络问题、服务器错误或数据处理错误。在控制台输出错误详情,并通过 Layui 框架的
layui.layer.msg
显示错误消息“请求翻译服务失败,请检查控制台”,以便用户能够了解错误原因并采取相应措施。
结果展示函数:
function displayResults(originalDescription, translatedText) { var part = translatedText.slice(7, -2); var resultContent = `<p>${part}</p>`; document.getElementById('result').innerHTML = resultContent; layui.layer.msg('结果获取成功'); }
这段代码定义了一个名为 displayResults
的函数,用于在网页上显示翻译后的文本结果,并通知用户结果已成功获取。这个函数接收两个参数:originalDescription
(原始描述,虽然在这个函数体中没有直接使用)和 translatedText
(翻译后的文本)。以下是函数的详细工作流程和逻辑:
-
文本处理:
translatedText.slice(7, -2)
这行代码从translatedText
中提取一部分文本。slice
方法的第一个参数7
表示从字符串的第八个字符开始截取,第二个参数-2
表示截取到字符串倒数第三个字符之前。这种处理通常用于去除字符串中不需要的前缀或后缀。 -
显示结果:
var resultContent =
<p>${part}</p>;
这行代码创建一个新的段落元素<p>
,并将处理后的文本(part
)嵌入其中。这个段落元素作为HTML代码被赋值给变量resultContent
。document.getElementById('result').innerHTML = resultContent;
这行代码将页面中ID为result
的元素(通常是一个容器,如<div>
)的内部HTML替换为resultContent
,从而在网页上显示翻译的结果。 -
用户反馈:
layui.layer.msg('结果获取成功');
这行代码使用 Layui 框架的消息功能来显示一条成功消息。这条消息告知用户翻译结果已成功显示在页面上,提供了直接的用户反馈。