You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AngularJS表单上传视频至API失败:TOP_ASSET显示为{}

Troubleshooting Your Angular Video Upload Issue

Hey there, let's figure out why your video upload is showing up as {} for the TOP_ASSET field in the network panel. I’ve gone through your code and found a few critical issues that are causing this problem—let’s break them down and fix them step by step.

Key Issues in Your Code

1. You’re Converting the File Object to JSON (Which Breaks It)

In your code, you’re taking the video File object and converting it to JSON with:

var myFile = jQuery.parseJSON(JSON.stringify($scope.video));

File objects are special browser-native objects that can’t be properly serialized to JSON. When you do this, you lose all the binary file data, which is why TOP_ASSET ends up as an empty object {} in the request. You should use the original File object directly instead of converting it.

2. You’re Sending a Regular JSON Request Instead of FormData

Uploading binary files (like videos) can’t be done with a standard JSON request—you need to use FormData instead. Your current approach sends a JSON payload, which can’t handle the video’s binary data. Even though your image works with base64 encoding, videos are usually too large for base64 (it increases file size by ~33%), so using FormData is the right approach for both files.

3. Unreliable Timing with $timeout

You’re using a hardcoded 3-second $timeout to wait for the FileReader to finish encoding the image. This is risky—if the image takes longer than 3 seconds to encode, your request will send incomplete data. Instead, we should use Promises to wait for the FileReader to actually finish before sending the request.

Fixed Code Implementation

Here’s the revised version of your uploadFile function with these issues addressed:

$scope.uploadFile = function (callback, e) {
    $scope.video = document.getElementById('fileVideo').files[0];
    if (!$scope.video) {
        console.log("No video file selected");
        return;
    }

    // Check video file size first
    if ($scope.video.size >= 209715200) { // 200MB limit
        console.log("File terlalu besar");
        return;
    }

    // Handle image encoding with Promises
    const imageEncodePromise = new Promise((resolve) => {
        let encodeTemp = "";
        // Assuming file2 is the image uploader
        angular.forEach($scope.uploader1.queue, function (value, index) {
            const reader = new FileReader();
            reader.readAsDataURL(value._file);
            reader.onload = function (ev) {
                const base64 = ev.target.result.substring(ev.target.result.indexOf(',') + 1);
                encodeTemp += base64 + ' ';
                // Resolve when all images are processed
                if (index === $scope.uploader1.queue.length - 1) {
                    resolve(encodeTemp.trim());
                }
            };
        });
        // If no images are selected, resolve empty string
        if ($scope.uploader1.queue.length === 0) {
            resolve("");
        }
    });

    // Wait for image encoding to finish, then send request
    imageEncodePromise.then((encodedImage) => {
        // Create FormData for the request
        const fd = new FormData();
        fd.append('TERMINAL_ID', $scope.getTerminalByID);
        fd.append('TOP_ASSET', $scope.video); // Use original File object
        fd.append('BOTTOM_ASSET', encodedImage);
        fd.append('DESCRIPTION', $scope.description);

        // Send the FormData via POST
        callApi.callPostApi('uploadUpdateTerminalAsset', fd, {
            headers: { 'Content-Type': undefined } // Let browser set correct Content-Type
        }).then(function (response) {
            if (response.STATUS === "failed") {
                console.log("Upload failed:", response);
            } else {
                // $state.go('restricted.dashboard');
                console.log("Upload successful!");
                if (callback) callback();
            }
        }).catch(function(error) {
            console.error("Error during upload:", error);
        });
    });
};

Additional Notes

  • FormData Headers: When sending FormData, make sure your callPostApi function sets the Content-Type header to undefined (or lets the browser set it automatically). This ensures the browser adds the correct multipart/form-data boundary, which is required for file uploads.
  • FileReader Cleanup: I removed the global $scope.reader1 and used a local variable inside the loop to avoid overwriting the reader instance for multiple files.
  • Error Handling: Added checks for missing video files and proper error catching in the API call.

This should fix the issue where TOP_ASSET shows up as {}—now the actual video file will be sent in the request, and the image encoding will reliably complete before the request is sent.

内容的提问来源于stack exchange,提问作者William

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:03:47