我是编程新手,在 React 文件中创建下载按钮时遇到了一些困难。简而言之,我使用 Kotlin Spring Boot 构建了一个 API,并使用 JSON 对其进行了测试。现在,我尝试通过 React 使用这个 API。
我的困难在于下载功能。该按钮下载文件,但它显示为空。但是,当我检查该元素时,该文件及其所有内容都会出现在“源控制台”(Safari) 中,允许我保存它。
您能帮我解释一下为什么下载按钮不显示 PDF 内容吗?我该怎么做才能解决这个问题?
有关我的 GitHub 的更多信息:https://github.com/raysatownsend/Consumindo_Api_React/blob/main/src/pages/Books/index.js
谢谢你!
期待对我的代码说明的帮助。可能是错的。
我的代码如下:
导出默认函数 Books() {
const [books, setBooks] = useState([]);
const [page, setPage] = useState(0);
const [files, setFiles] = useState([]);
const navigate = useNavigate();
const accessToken = localStorage.getItem("accessToken");
const username = localStorage.getItem("username");
const authorization = {
headers:{
Authorization: `Bearer ${accessToken}`
}
};
const contentType = {
headers: {
"Content-Type": "application/octet-stream",
"Content-Type": "application/pdf"
}
}
const responseType = {
headers: {
responseType: 'blob',
}
}
useEffect(() => {
fetchMoreBooks();
}, [accessToken])
async function fetchMoreBooks() {
const response = await api.get(`api/books/v1?page=${page}&size=8&direction=asc`, authorization)
setBooks([...books, ...response.data._embedded.authorVOList]);
setPage(page + 1);
}
async function editBook(id) {
try {
navigate(`/books/book/new/${id}`);
} catch (error) {
alert("Edit book failed, please try again.")
}
}
async function downloadBook() {
try {
const response = await api.get("api/file/v1/downloadFile/PRESSMAN_Engenharia_de_software_Uma_Abor.pdf", authorization, contentType, responseType)
// Create a Blob object from the response data
const blob = new Blob([...files, ...response.data], { type: response.headers["Content-Type"] });
// Create a temporary anchor element
const downloadLink = document.createElement('a');
downloadLink.href = window.URL.createObjectURL(blob);
downloadLink.setAttribute('download', 'PRESSMAN_Engenharia_de_software_Uma_Abor.pdf'); // Set the download attribute with desired filename
document.body.appendChild(downloadLink);
// Trigger the download by programmatically clicking the anchor element
downloadLink.click();
// Cleanup
window.URL.revokeObjectURL(downloadLink.href);
} catch (error) {
alert("ERROR: Can't download choosen item, please try again.");
}
}
async function deleteBook(id) {
try {
await api.delete(`api/books/v1/${id}`, authorization)
setBooks(books.filter(book => book.id !== id))
} catch (error) {
alert("ERROR: Can't delete choosen item, please try again.")
}
}
async function logout() {
try {
localStorage.clear()
navigate("/")
} catch (error) {
alert("Logout failed, please try again.")
}
}
return (
<div className="book-container">
<header>
<img src={logoImage} alt="Logo" />
<span>Bem-Vindo, <strong>{username.toUpperCase()}</strong>!</span>
<Link className="button" to="book/new/0">Add New Book</Link>
<button onClick={logout} type="button">
<FiPower size={18} color='#251FC5'/>
</button>
</header>
<h1>Registered Books</h1>
<ul>
{books.map(book => (
<li key={book.id}>
<strong>Title:</strong>
<p>{book.title}</p>
<strong>Author:</strong>
<p>{book.author}</p>
<strong>Price:</strong>
<p>{Intl.NumberFormat('pt-BR', {style: 'currency', currency: 'BRL'}).format(book.price)}</p>
<strong>Release Date:</strong>
<p>{Intl.DateTimeFormat('pt-BR').format(new Date(book.launchDate))}</p>
<button onClick={() => editBook(book.id)} type="button">
<FiEdit size={20} color="#251FC5"/>
</button>
<button onClick={() => downloadBook()} type="button">
<FiDownload size={20} color="#251FC5"/>
</button>
<button onClick={() => deleteBook(book.id)} type="button">
<FiTrash2 size={20} color="#251FC5"/>
</button>
</li>
))}
</ul>
<button className="button" onClick={fetchMoreBooks} type="button">Load more</button>
</div>
);
}
代码很多,但我发现你的
downloadBook
函数不太正确。你在那里做了不必要的步骤。files
数组中的要点。
这是简化的工作功能,您可以根据您的需要进行调整:
async function downloadBook() {
// fetching data from a url, getting an response if everything is ok
// I use simple fetch here (not axios, etc)
const response = await fetch('your url');
// now creating a blob from response, it should have correct type automatically
const resBlob = await response.blob();
// Create a temporary anchor element
const downloadLink = document.createElement('a');
downloadLink.href = window.URL.createObjectURL(resBlob);
downloadLink.setAttribute('download', 'PRESSMAN_Engenharia_de_software_Uma_Abor.pdf'); // Set the download attribute with desired filename
document.body.appendChild(downloadLink);
// Trigger the download by programmatically clicking the anchor element
downloadLink.click();
// Cleanup
window.URL.revokeObjectURL(downloadLink.href);
}