# Upload & Download (Front-end)

## Upload

* In order to pass the binary data to the server, the content type- multipart/form-data must be required
* The `multipart/form-data` content type is designed to allow for the transmission of binary data, such as files, over HTTP. With this content type, the data in the request body is divided into multiple parts, each identified by a unique boundary string. Each part contains a header and a body, where the body contains the binary data of the file.

```javascript
const url = `${process.env.REACT_APP_IMAGE_SERVICE_URL}/api/images`;
      const formData = new FormData();
      formData.append("file", file);
      formData.append("type", "hi");
      const { data } = await axios.post(url, formData);
```

```html
<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="text" name="text" value="text default" />
    <input type="file" name="file1" />
    <input type="file" name="file2" />
    <button type="submit">Submit</button>
</form>
```

## Download

* For downloading file, there are 2 types of url, data url and server url for a tag href
* Download attribute on a tag can be used to specify the name of file that to be downloaded

#### Data Url

* Can be used for download file without uploading to server

* The format is&#x20;

  ```
  data:[<mediatype>][;base64],<data>
  ```

* Media type: mime type, e.g: image/png

* data:  the encoded data in base64 format which is converted from file binary data

```html
The text/plain data Hello, World!
data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==

base64-encoded version of the above
data:,Hello%2C%20World%21

// excel file
data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64, xxxx
```

#### Server Url

* File url that uploaded to server
* Streaming can be allowed when using server url to download file
* If  authentication  is needed, the hash can be get from api firstly, and then combine with server url to obtain the file, e.g: <https://backend.com/test.txt?code=xxxxxx>

#### Blob (Binary large object)

* Blob data is a file-like object of immutable, raw data; they can be read as text or binary data, or converted into stream
* When the server api return binary file (e.g: file), the endpoint is actually a file url
* Sometimes, we need to fetch data instead of using a tag with server url to download file directly, for example: need to pass token into header
* We need to get the blob data from response, make good use of blob data to create another url to new a tag to download file

```javascript
 const downloadLink = document.createElement('a');
 downloadLink.href = URL.createObjectURL(blob);
 console.log(downloadLink.href);
 // blob:https://localhost:3000/d84cc112-85a0-4e8e-8319-233403c9c69e
 downloadLink.download = "123.csv";
 document.body.appendChild(downloadLink);
 downloadLink.click();
```

## Streaming

<figure><img src="https://1374779285-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MFW3x2aqEO8GF2kr3VU%2Fuploads%2Ffhes0Vfljtk3yUoHkLo8%2Fimage.png?alt=media&#x26;token=ddc3220a-16b8-4ba5-a8b3-3ed23d3f7981" alt=""><figcaption></figcaption></figure>

* For the default api calling, the client will wait for the server until the whole of the server data is ready
* After using streaming on front-end, the client can read the server response by chunks until the whole of data is get.&#x20;
* It can be used to trace the progress of getting data from backend

```javascript

const reader = res.body.getReader();
// let sum = 0;
const stream = new ReadableStream({
	start(controller) {
	  return pump();
	  function pump() {
		return reader.read().then(({ done, value }) => {
		  // When no more data needs to be consumed, close the stream
		  if (done) {
			controller.close();
			return;
		  }
		  // Enqueue the next data chunk into our target stream
		  controller.enqueue(value);
		  // Can Conduct the logic based on the current chunk data (value)
		  // console.log("value",value);
		  // sum+=value.length;
		  // console.log("sum",sum);
		  return pump();
		});
	  }
	},
  });
const response = new Response(stream);
console.log(response);
return response.blob();
```

## References

{% embed url="<https://developer.mozilla.org/en-US/docs/Web/API/Streams_API>" %}

{% embed url="<https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs#encoding_data_into_base64_format>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://petercheng7788.gitbook.io/developer-note/backend/file-handling/upload-and-download-front-end.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
