Skip to main content

[JavaScript] Unable to Upload File to Parent

  • March 18, 2024
  • 6 replies
  • 281 views

  • New Participant
  • 3 replies

I have abandoned using Box with PHP because the support is abysmal. Since this is an internal only application anyways, I’m using JavaScript.


I can successfully download a file by searching for it using the /search?query=filename.ext&type=file endpoint. In the response, there are several entries, but I can find the specific file I’m looking for by using JavaScript’s find method checking the entry’s name and parent.id.


When I try to upload a file using the /files/content endpoint, I am getting a 404 from the response using this function:


async uploadFile(filename, rawFiles) {

	if (!this.#accessToken) {

		const errorMessage = 'Access Token is not set. Please authenticate first.'

		console.error(errorMessage);

		throw new Error(error);

	}



	const uploadUrl = 'https://api.box.com/2.0/files/content';

	const parentFolderId = '-redacted-';

	

	if (rawFiles?.length === 0) {

		const errorMessage = 'Please select a file.'

		console.error(errorMessage);

		throw new Error(error);

	}

	const file = rawFiles[0];

	const formData = new FormData();

	formData.append('attributes', JSON.stringify({

		name: filename,

		parent: { id: parentFolderId }

	}));

	formData.append('file', file);

  

	try {

		const response = await fetch(uploadUrl, {

			method: 'POST',

			headers: {

				'Authorization': `Bearer ${this.#accessToken}`

			},

			body: formData

		});

  

	  if (!response.ok) {

		throw new Error(`Server returned ${response.status}: ${response.statusText}`);

	  }

  

	  await response.json();

	} catch (error) {

		console.error('Upload error:', error);

		throw new Error(error);

	}

}


I don’t think this is a permission issue because with my search entries because I can confirm that value in the parent.id matches the value I’m passing in my parentFolderId variable. However, the only reason a 404 can be returned per the documentation is:



Returns an error if the parent folder does not exist or if the user is not authorized to access the parent folder.


6 replies

CodeBoxSeb
  • Participating Frequently
  • 58 replies
  • March 18, 2024

Hi @dday9


I’m not sure if you should use https://api.box.com/2.0/files/content or https://upload.box.com/api/2.0/files/content for your POST query


Would it be possible to show us the full error message that you have for your 404 ?


  • Author
  • New Participant
  • 3 replies
  • March 18, 2024

@CodeBoxSeb - There is no error message being returned by the request, only a 404 response. These are the response headers:


Request URL: https://api.box.com/2.0/files/content

Request Method: POST

Status Code: 404 Not Found

Referrer Policy: strict-origin-when-cross-origin

Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000

Box-Request-Id: -redacted-

Content-Length: 0

Content-Type: text/html; charset=UTF-8

Date: Mon, 18 Mar 2024 13:27:56 GMT

Strict-Transport-Security: max-age=31536000

Via: 1.1 google

X-Envoy-Upstream-Service-Time: 16


Edit - Changing the URL to use the upload subdomain rather than the api subdomain errors as well, only the error returned is a CORS error:



Cross-Origin Resource Sharing error: PreflightMissingAllowOriginHeader



Edit 2 - So I converted my upload to PHP and made the call through PHP and it works. I don’t understand why doing it from the browser causes it to fail.


smartoneinok Box
Forum|alt.badge.img
  • Senior Developer Advocate
  • 181 replies
  • March 19, 2024

Does the client id/application you are making the call with have underlying permissions to upload to the folder? This may not be your user, as JWT and CCG auth types get a service account to represent them upon approval.


  • Author
  • New Participant
  • 3 replies
  • March 20, 2024

@smartoneinok - Yes, if you look at my second edit it works fine in PHP using the same client id, client secret, and enterprise id. It just isn’t working through JavaScript.


smartoneinok Box
Forum|alt.badge.img
  • Senior Developer Advocate
  • 181 replies
  • March 20, 2024

Alright! Let me dig in a bit further. Can I ask why you aren’t using an official Box SDK GitHub - box/sdks: SDKs, CLI and other tools for using Box Platform? It looks like you are just using native JS.


smartoneinok Box
Forum|alt.badge.img
  • Senior Developer Advocate
  • 181 replies
  • March 20, 2024

The follow code worked for me with a ccg app and my local url added to the cors listing in the box config. I used the global http-server package to host it at a local url. I also updated the folder id in the js to be one my app had access to.


HTML


<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Box File Upload</title>

    <link rel="stylesheet" href="style.css">

    <link rel="icon" href="favicon.ico" type="image/x-icon">

</head>

<body>



<div class="container">

    <h2>Box File Upload</h2>

    <input type="text" id="tokenInput" placeholder="Enter your Box API token here">

    <input type="file" id="fileInput">

    <button id="uploadButton">Upload</button>

</div>



<script src="script.js"></script>

</body>

</html>


CSS


body {

    font-family: Arial, sans-serif;

    display: flex;

    justify-content: center;

    align-items: center;

    height: 100vh;

    margin: 0;

    background-color: #f4f4f4;

}



.container {

    background: #fff;

    padding: 20px;

    border-radius: 8px;

    box-shadow: 0 2px 4px rgba(0,0,0,0.1);

    text-align: center;

}



input[type="text"], input[type="file"] {

    margin: 10px 0;

    padding: 10px;

    width: 80%;

    border-radius: 5px;

    border: 1px solid #ddd;

}



button {

    padding: 10px 20px;

    background-color: #007bff;

    color: #fff;

    border: none;

    border-radius: 5px;

    cursor: pointer;

}



button:hover {

    background-color: #0056b3;

}


JS


document.addEventListener('DOMContentLoaded', function() {

    document.getElementById('uploadButton').addEventListener('click', function() {

        const token = document.getElementById('tokenInput').value.trim();

        const fileInput = document.getElementById('fileInput');

        const file = fileInput.files[0];



        if (!token) {

            alert('Please enter your Box API token.');

            return;

        }



        if (!file) {

            alert('Please select a file to upload.');

            return;

        }



        const formData = new FormData();

        formData.append('file', file);

        // The file's name is accessed directly from the file object

        formData.append('attributes', JSON.stringify({

            name: file.name,

            parent: { id: '0' } // Assuming you're uploading to the root folder or you can change it

        }));



        fetch('https://upload.box.com/api/2.0/files/content', {

            method: 'POST',

            headers: {

                Authorization: `Bearer ${token}`

            },

            body: formData

        })

        .then(response => {

            if (!response.ok) {

                return response.json().then(body => {

                    throw new Error(JSON.stringify(body)); // Convert the JSON body to string and throw it as an error

                });

            }

            return response.json();

        })

        .then(data => {

            console.log('Upload successful:', data);

            alert('File uploaded successfully.');

        })

        .catch(error => {

            console.error('Upload error:', error.message); // This contains the stringified JSON error

        

            let errorMessage = 'Upload failed. Please check the console for more details.';

            try {

                const errorObj = JSON.parse(error.message); // Parse the string back into an object

        

                if (errorObj && errorObj.message) {

                    console.error('Error message:', errorObj.message); // Log the error message

                    errorMessage += ` Error: ${errorObj.message}`;

                }

                if (errorObj && errorObj.code) {

                    console.error('Error code:', errorObj.code); // Log the error code

                }

            } catch (parseError) {

                console.error('Error parsing error message:', parseError);

            }

        

            alert(errorMessage);

        });        

    });

});


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings