MTurk 如何在提交任务时将文件上传到 S3

MTurk how to upload file to S3 when task is submitted

我正在尝试在 Amazon MTurk 上创建一个任务,工作人员将在其中收集一些数据并在准备好并提交任务时上传单个文件。提交任务后,我想将文件上传到我链接的 S3 存储桶 - 这主要基于 this tutorial.

但是,文件有时上传成功,有时不成功。由于S3.upload函数是异步的,所以看起来有时任务提交完成还没有完成文件上传。我是javascript新手:我试着让它同步发生,但它仍然不能正常工作。这是我的 javascript 代码:

<script>
    let config = {
        region: 'xxx',
        pool: 'xxx',
        bucket: 'xxx'
    }
    
    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 = function (event) {
        $("#status").text("Uploading...");
    
        let file = $("#file").prop('files')[0];
        if (file === null || file === undefined) {
            alert("You must upload a file before submitting.");
            $("#status").text("");
            return false;
        }
    
        console.log('Filename: ' + file.name);
    
        let workerId = turkGetParam('workerId');
        let fileKey = '${food_name}' + '/' + workerId + '-' + file.name;
    
        return upload_to_s3(file, fileKey);
    };
  
    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;
        }
    }
  
    // Validate and upload file on submit
    window.onload = function() {document.getElementById('submitButton').setAttribute('onclick', 'return start_upload()'); }
</script>

这里是这个任务(HIT)布局的相关部分:

如何在任务完成前确保文件上传完成?我看到我可以覆盖 MTurk 添加的默认提交按钮,但如果可能的话我宁愿不这样做。

我发现了问题:S3#upload returns一个ManagedUpload对象,但并不意味着文件上传完成。我现在正在使用 promises 并在回调中手动提交表单。请注意,该表单默认由 MTurk 提​​供。我只是通过它的 ID 找到它并手动调用 submit 函数。

作为参考,这里是工作代码:

<script>
    let config = {
        region: 'xxx',
        pool: 'xxx',
        bucket: 'xxx'
    }
    
    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 = function (event) {
        $("#status").text("Uploading, please wait...");
    
        let file = $("#file").prop('files')[0];
        if (file === null || file === undefined) {
            alert("You must choose a file before submitting.");
            $("#status").text("");
            return false;
        }
    
        let workerId = turkGetParam('workerId');
        let fileKey = '${food_name}' + '/' + workerId + '-' + file.name;
    
        upload_to_s3(file, fileKey);
        
        return false;
    };
  
    upload_to_s3 = (file, fileKey) => {
        const params = {
            Key: fileKey,
            Body: file,
            ContentType: file.type,
            ACL: 'bucket-owner-full-control'
        };
    
        let promise = s3.upload(params).promise();
        promise.then( (data) => {
            console.log("Upload completed");
            $("#status").text("Success.");
            
            const form = document.getElementById('mturk_form');
            form.submit();
        }, (err) => {
            console.log("Upload failed!!!", err);
            alert("Failed to upload, please try again. If the problem persists, contact the Requester.");
            $("#status").text("");
        } );
    }
  
    // Validate and upload file on submit
    window.onload = function() {document.getElementById('submitButton').setAttribute('onclick', 'return start_upload()'); }
</script>