MTurk任务提交时如何确保文件优先完成上传到绑定的S3存储桶
Amazon MTurk S3文件上传后再提交任务修复方案
核心问题原因
你的代码失效的核心是异步逻辑未与表单提交绑定:
upload_to_s3是异步函数,你当前的调用逻辑不会等待上传结果返回,就会直接触发MTurk默认的提交流程,导致上传还没完成任务就已经提交了- 原生onclick事件不会等待异步函数执行完毕,只要返回值不是
false就会继续执行后续默认行为
修复逻辑
不修改MTurk原生提交按钮,只调整触发逻辑:
- 点击提交按钮时先阻止默认提交行为
- 添加上传状态锁,避免重复点击触发多次上传
- 等待S3上传成功后,手动调用MTurk原生表单的提交方法,完全兼容平台原有逻辑
修改后完整代码
<script> let config = { region: 'xxx', pool: 'xxx', bucket: 'xxx' } // 新增:上传状态锁,防止重复提交 let isUploading = false; AWS.config.region = config.region; AWS.config.credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId: config.pool, }); var s3 = new AWS.S3({ apiVersion: '2006-03-01', params: {Bucket: config.bucket}, }); // 修改为异步函数,接收事件对象 start_upload = async function (event) { // 阻止默认的表单提交行为 event.preventDefault(); // 上传中直接拦截重复点击 if (isUploading) return false; $("#status").text("Uploading..."); isUploading = true; let file = $("#file").prop('files')[0]; if (file === null || file === undefined) { alert("You must upload a file before submitting."); $("#status").text(""); isUploading = false; return false; } console.log('Filename: ' + file.name); let workerId = turkGetParam('workerId'); let fileKey = '${food_name}' + '/' + workerId + '-' + file.name; // 等待上传结果 const uploadSuccess = await upload_to_s3(file, fileKey); if (uploadSuccess) { // 上传成功,手动触发MTurk默认表单提交,MTurk默认表单ID为mturk_form document.getElementById('mturk_form').submit(); } else { isUploading = false; } }; upload_to_s3 = async (file, fileKey) => { const params = { Key: fileKey, Body: file, ContentType: file.type, ACL: 'bucket-owner-full-control' }; try { console.log("Starting upload..."); const data = await s3.upload(params).promise(); console.log("Done uploading file"); $("#status").text("Success."); return true; } catch (err) { console.log("Error uploading data. ", err); alert("Failed to upload, please try again. If the problem persists, contact the Requester."); $("#status").text(""); return false; } } // 修改绑定方式,用addEventListener接收事件对象 window.onload = function() { document.getElementById('submitButton').addEventListener('click', start_upload); } </script>
注意事项
- 如果你自己修改过MTurk默认表单的ID,把代码里的
mturk_form替换为你实际的表单ID即可 - 状态锁会在上传失败后自动释放,工人可以重新尝试上传,不需要刷新页面
内容的提问来源于stack exchange,提问作者Egemen
相关产品推荐
相关产品推荐

