Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Azure support #1591

Closed
nagyv opened this issue May 23, 2019 · 14 comments
Closed

Azure support #1591

nagyv opened this issue May 23, 2019 · 14 comments
Labels

Comments

@nagyv
Copy link
Contributor

nagyv commented May 23, 2019

As Azure does not provide an S3 compatible API, I'm wondering if anyone has experience integrating Uppy with Azure storage?

@nagyv
Copy link
Contributor Author

nagyv commented May 24, 2019

I've got it working using Aws-s3 plugin's getUploadParameters.

Thanks for uppy!

@nagyv nagyv closed this as completed May 24, 2019
@mpoozd
Copy link

mpoozd commented Jun 22, 2019

@nagyv
can you please share how did you use it with azure storage ?

@nagyv
Copy link
Contributor Author

nagyv commented Jun 23, 2019

Sure. A few notes will follow the code.

  const uppy = Uppy({
    meta: { type: 'avatar' },
    restrictions: {
      maxNumberOfFiles: 1,
      allowedFileTypes: ['image/*', '.jpg', '.jpeg', '.png', '.gif']
    },
    autoProceed: false,
    allowMultipleUploads: false
  })

  uppy.use(AwsS3, {
    getUploadParameters: file => {
      return getAzureSas({
        filename: file.name,
        contentType: file.type,
        extension: file.extension
      })
        .then(data => {
          return {
            method: 'PUT',
            url: data.url,
            fields: {},
            headers: {
              'x-ms-blob-type': 'BlockBlob'
            }
          }
        })
    }
  })
  uppy.on('upload-success', (file, uploadResp) => {
    saveAvatarUrl(uploadResp.uploadURL)
      .then(() => {
        uppy.getPlugin('react:Dashboard').closeModal()
      }, err => {
        errorLog(err)
        uppy.info(t('user.save-failed'), 'error', 3000)
      })
  })

I'm using uppy with React. Thus the uppy.getPlugin('react:Dashboard').closeModal().
getAzureSas and saveAvatarUrl are my custom functions the get a Shared Access Signature from Azure and to save the final URL in my backend, respectively.

@smcguire36
Copy link

@nagyv Can you provide your implementations of the getAzureSas and saveAvatarUrl custom functions? My team is looking at Uppy to replace our older plupload based uploader to upload files directly to Azure Blob Storage. I had implemented a prototype using FineUploader but I see that FU is now a dead project (as in no further updates). We would rather not be relying on a library that has no possibility of support or future upgrades as browsers change.

--Stewart McGuire

@nagyv
Copy link
Contributor Author

nagyv commented Sep 17, 2019

@smcguire36 you really won't benefit from my getAzureSas and saveAvatarUrl methods. They are simple window.fetch calls to my backend. The former returns a secure access signature, while the latter saves the image url returned on successful upload. The client side is just a window.fetch. The server side for generating a SAS is documented following the above link.

@smcguire36
Copy link

@nagyv I actually already have a ColdFusion backend endpoint that generates our SAS. I built it to implement FineUploader. Since I am not using React and only regular Javascript with jQuery I can implement my own functions using jQuery.

@theweiweiway
Copy link

theweiweiway commented Dec 7, 2019

Thanks for the code snippet. I'm trying to do something very similar to you, but my upload keeps failing. Any help would be greatly appreciated.
My code:

        this.uppy =
            Uppy({
                id: 'chat',
                restrictions: { maxFileSize: 20000000, maxNumberOfFiles: 1 },
                autoProceed: false,
                allowMultipleUploads: false
            })
                .use(AwsS3, {
                    getUploadParameters: file => {
                        axios.post('/api/azure/chat/write', {
                            fileName: file.name
                        })
                            .then((result) => {
                                return {
                                    method: 'PUT',
                                    url: result.data.url,
                                    fields: {},
                                    headers: {
                                        'x-ms-blob-type': 'BlockBlob'
                                    }
                                }
                            })
                            .catch((error) => {
                                console.log(error)
                            })
                    }
                })
                .on('upload-success', (file, data) => {
                    console.log('success!')
                })

I know for a fact that it's not my SAS, since i can upload the file perfectly fine through postman. Is there something with uppy I'm missing?

For reference, this is my endpoint function with @azure/storage-blob v12

const AzureStorageBlob = require("@azure/storage-blob")

const account = 'accountName'
const containerName = 'chats'
const sharedKeyCredential = new AzureStorageBlob.StorageSharedKeyCredential(account, process.env.AZURE_KEY);
const blobServiceClient = new AzureStorageBlob.BlobServiceClient(
    `https://${account}.blob.core.windows.net`,
    sharedKeyCredential
);

const getWriteChatSasUrl = async function (req, res, next) {
    const blobName = req.body.fileName
    try {
        const sas = await AzureStorageBlob.generateBlobSASQueryParameters({
            containerName,
            blobName,
            permissions: AzureStorageBlob.ContainerSASPermissions.parse("w"),
            protocol: 'https',
            startsOn: new Date(new Date().valueOf() - 86400),
            expiresOn: new Date(new Date().valueOf() + 86400),
        }, sharedKeyCredential)
        res.status(200).json({
            url: `https://${account}.blob.core.windows.net/${containerName}/${blobName}?${sas.toString()}`,
            fileName: req.body.fileName,
        })
    } catch (e) {
        console.log(e)
        // res.status(500).json('Internal server error')
    }
}

router.use('/chat/write', getWriteChatSasUrl)

@theweiweiway
Copy link

I just figured it out. I was missing a return right before my axios call.

@akshaybabloo
Copy link

Has anyone got through multipart upload to Azure? I am trying to upload 500 MB using the above technique and I get The request body is too large and exceeds the maximum permissible limit. error

@VishalBhanderi
Copy link

@akshaybabloo Did you manage to upload large files to Azure blobs?

@akshaybabloo
Copy link

@VishalBhanderi I couldn't. Left it for now.

@brecht-vermeersch
Copy link

I created a plugin for azure blob

https://www.npmjs.com/package/uppy-azure-blob

@stewartmcguire
Copy link

I created a plugin for azure blob

https://www.npmjs.com/package/uppy-azure-blob

Can your Azure Blob plugin be used with vanilla Javascript? Our current app doesn't use any JS framework or bundler.

--Stewart

@brecht-vermeersch
Copy link

The plugin requires a module bundler such as Vite, Parcel, Webpack, Rollup or others. This is because it depends on @azure/storage-blob which also requires a bundler to work in the browser

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants