Search code examples
pythonreactjsdjangoaxios

How to download docx file with django\react [EDITED: axios]?


I try to download test.docx but file size and content incorrect.
As example source file size is 14kb, downloaded 22kb

Source file contain table(if this important)

But it's work correct with pdf and txt

view.py

@method_decorator(csrf_exempt, name="dispatch")
class TestDownloadView(View):

    def post(self, request):
        filename = "./test.docx"
        with open(filename, "rb") as blank:
            content = blank.read()
            response = HttpResponse(
                content,
                content_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
            )
            response["Content-Length"] = len(content)
            response["Content-Disposition"] = "attachment; filename=test.docx"
            return response

App.tsx

function App() {

        const dload = () => {
                axios.post('http://127.0.0.1:8000')
                        .then(response => {
                                const type = response.headers['content-type']
                                const href = URL.createObjectURL(new Blob([response.data], { type: type }));
                                const link = document.createElement('a');
                                link.href = href;
                                link.setAttribute('download', 'file.docx');
                                document.body.appendChild(link);
                                link.click();
                                document.body.removeChild(link);
                                URL.revokeObjectURL(href);
                        })
        }
        return (
                <>
                        <button onClick={dload}> Click </button>
                </>
        )
}

I already try different content-type.

Edited So the problem not in Django. I rewrite axios to fetch like this:

                fetch('http://127.0.0.1:8000', { method: "POST" })
                        .then(response => response.blob())
                        .then(blob => {
                                const href = URL.createObjectURL(blob);
                                const link = document.createElement('a');
                                link.href = href;
                                link.setAttribute('download', 'file.docx');
                                document.body.appendChild(link);
                                link.click();
                                document.body.removeChild(link);
                                URL.revokeObjectURL(href);
                        })

And this work. But i still need axios solution or any idea. Whats wrong?


Solution

  • If someone find this helpful this is solution

    axios.post('http://127.0.0.1:8000', {}, { responseType: "blob" }) 
    // axios post with empty data and response type(important`)
        .then(response => {
            const type = response.headers['content-type']
            console.log(response.headers)
            const href = URL.createObjectURL(new Blob([response.data], { type: type }));
            const link = document.createElement('a');
            link.href = href;
            link.setAttribute('download', 'file.docx');
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            URL.revokeObjectURL(href);
    })