2

I have some large attachment in event.

At first, my link code is

<a :download="scope.row.name" :href="`data:${scope.row.type};base64,${scope.row.contentBytes}`">download</a>

However, when I get the attachment information from graph api, it will be very slow because of the big contentBytes even though I bind onclick to be lazy.

40MB attachment will take more than 3mins at the frontend.

Are there some methods can make user onclick the file then it will download in user background like every file on the other website(OneDrive, GoogleDrive...)

download

I use Vue with element UI, so some Js sample will be helpful.

-- updated

My method now:

When I click download, it will create a $value request enter image description here

then after about 1 min it finally fininsh.

check the link for the complete video.

-- code

// graphapi.js
export function getAttachment(eventId, attachmentId) {
  return request({
    url: `/events/${eventId}/attachments/${attachmentId}/$value`,
    method: 'get'
  })
}
// form.vue
// template
 <el-table-column v-if="action === 'edit'" width="150px" label="操作">
          <template slot-scope="scope">
            <el-button size="small" type="text">
              <a @click.prevent="downloadAttachment(scope.row.id)">download</a>
            </el-button>
            <el-button size="small" type="text" @click="deleteAttachment(scope.row.id)">remove</el-button>
          </template>
        </el-table-column>
// script
downloadAttachment(attachmentId) {
      const attachment = getAttachment(this.$route.params.id, attachmentId)
const link = document.createElement('a')
link.href = `data:${attachment.type};base64,${attachment.contentBytes}`
link.click()
    },
kissu
  • 40,416
  • 14
  • 65
  • 133
Sanji
  • 83
  • 1
  • 7
  • I would've though the `download` attribute would mean that the `href` would be downloaded - that's what the documentation for `` says - ` even though I bind onclick to be lazy` you do what now? there is no `onclick` – Jaromanda X Sep 15 '22 at 10:10
  • on what user/browser action you want the download to be started ? – Емил Цоков Sep 15 '22 at 10:23
  • You want it to be downloaded to some other place basically? Not directly on the UI? – kissu Sep 15 '22 at 10:50
  • @JaromandaX that is my first writeing code, now is `download` – Sanji Sep 15 '22 at 10:56
  • @ЕмилЦоков It's simple, a download button for the user, he click then download start. The problem is graph api response too slow. – Sanji Sep 15 '22 at 10:58
  • @kissu on the UI, a download button for the user – Sanji Sep 15 '22 at 10:59
  • Did you tried that one: https://stackoverflow.com/a/67118753/8816585 ? – kissu Sep 15 '22 at 11:00
  • @kissu the solution is about making a download, but my problem is when I call graph API, it sends the response slowly because of the big base64 contentbytes. I want to find some way avoid it. – Sanji Sep 15 '22 at 11:08
  • What could be a solution in this case? Hosting it somewhere else as a blob will not help if the Internet connection is slow. Not sure how you can expect to do here. Cache it somehow? 40MB is big but could maybe be optimized somehow? What kind of data is it? – kissu Sep 15 '22 at 11:12
  • Put the code you're asking about in the question to avoid misunderstandings – Jaromanda X Sep 15 '22 at 11:20
  • @kissu I updated the information in my problem. I think the solution will be how can I run the download in the user's browser download area like my picture 1 or maybe there are some methods to make the graph api response speed up. The data is contentBytes(base64 from file) – Sanji Sep 15 '22 at 11:37
  • Oh, I understand the issue a bit better now (thanks to the video), sorry. Yeah, you could host the finished file somewhere on an S3 bucket or any kind of storage with a CDN if you want to have something fast. Optimizing it on the server will not be enough overall IMO because of too long delays. Better to let user's browser download the file on background (if hosted) rather than waiting for some API response. – kissu Sep 15 '22 at 11:40
  • @kissu do you mean if user upload the file then I should call graph API and make a file copy to cdn? – Sanji Sep 15 '22 at 11:49
  • @JaromandaX the code infomation is updated – Sanji Sep 15 '22 at 11:54
  • 1
    Yeah, base64'ing take too much time, so let the user upload the file to some CDN. Compress it properly on the backend and when asked, return the URL of the asset rather than doing that on the API. Will also be more scalable because, when you'll get more traffic your API will be busy and will need to handle quite some load if 10 people ask for the resource at the same time. – kissu Sep 15 '22 at 12:10
  • @kissu thx, your answer can be considered, but I hope there are more methods. I think there are some api in ms graph can make the request faster. Maybe graph api can get-range request – Sanji Sep 15 '22 at 13:10
  • 1
    What happens at the end of the API response? You still need to download it, right? Even if you make it faster, it will still not be fast enough IMO + you will still get the load on the server. As told before, you can also optimize the file but at the end, I'm not even sure why you do base64 it to start. Do you need it? – kissu Sep 15 '22 at 13:53
  • @kissu Thank you again. After these days, I'll take your advice. You are right, whatever I do, I actually need to get the load on the server, so make a copy to fast download is a good idea. – Sanji Sep 17 '22 at 12:56

1 Answers1

1

Host your images on a CDN, that way you will be able to download them directly without any delay + you will not put any load onto your server (hence being able to serve files to people faster around the world without your server crashing).

Depending on where you host your app, you may have it included, could use Cloudfront or Cloudinary.

kissu
  • 40,416
  • 14
  • 65
  • 133