gpt4 book ai didi

reactjs - 如何使用 gapi 将图像上传到谷歌驱动器并使用react

转载 作者:行者123 更新时间:2023-12-04 08:37:15 26 4
gpt4 key购买 nike

我正在尝试将图像上传到谷歌驱动器。我按照本教程上传文件,我可以上传一个简单的文件,但是当我尝试上传图像时,我得到了损坏的图像。事实上,文件已上传,但我要查看的图像已损坏。我知道问题出在请求的正文中,但我不知道在哪里,因为这是一种奇怪的方式(边界、定界符等)。除了图像的内容外,一切正常,所以您只需要查看上传图像的 post 方法。这是我的代码:

import { Upload } from 'antd';
import React, { Component } from 'react';

var SCOPE = 'https://www.googleapis.com/auth/drive.file';
var discoveryUrl = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest';


class App extends Component {
state = {
name: '',
googleAuth: '',
body: ''
}
componentDidMount(){
var script = document.createElement('script');
script.onload=this.handleClientLoad;
script.src="https://apis.google.com/js/api.js";
document.body.appendChild(script);
}


initClient = () => {
try{
window.gapi.client.init({
'apiKey': "apikey",
'clientId': "clientid",
'scope': SCOPE,
'discoveryDocs': [discoveryUrl]
}).then(() => {
this.setState({
googleAuth: window.gapi.auth2.getAuthInstance()
})
this.state.googleAuth.isSignedIn.listen(this.updateSigninStatus);
document.getElementById('signin-btn').addEventListener('click', this.signInFunction);
document.getElementById('signout-btn').addEventListener('click', this.signOutFunction);

});
}catch(e){
console.log(e);
}
}


signInFunction =()=>{
console.log(this.state.googleAuth)
this.state.googleAuth.signIn();
console.log(this.state.googleAuth)
this.updateSigninStatus()
}

signOutFunction =()=>{
this.state.googleAuth.signOut();
this.updateSigninStatus()
}

updateSigninStatus = ()=> {
this.setSigninStatus();
}

setSigninStatus= async ()=>{
console.log(this.state.googleAuth.currentUser.get())
var user = this.state.googleAuth.currentUser.get();
console.log(user)
if (user.wc == null){
this.setState({
name: ''
});
}
else{
var isAuthorized = user.hasGrantedScopes(SCOPE);
if(isAuthorized){
console.log('USER')
console.log(user)
this.setState({
name: user.vt.Ad
});

const boundary = '-------314159265358979323846';
const delimiter = "\r\n--" + boundary + "\r\n";
const close_delim = "\r\n--" + boundary + "--";
var fileName='mychat123.png';
var contentType='image/png'
var metadata = {
'name': fileName,
'mimeType': contentType
};

var multipartRequestBody =
delimiter + 'Content-Type: application/json\r\n\r\n' +
JSON.stringify(metadata) +
delimiter +
'Content-Type: ' + contentType + '\r\n';

multipartRequestBody += + '\r\n' + this.state.body;
multipartRequestBody += close_delim;

console.log(multipartRequestBody);
var request = window.gapi.client.request({
'path': 'https://www.googleapis.com/upload/drive/v3/files',
'method': 'POST',
'params': {'uploadType': 'multipart'},
'headers': {
'Content-Type': contentType
},
'body': multipartRequestBody
});

request.execute(function(file) {
console.log(file)
});
}
}
}

getBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
}


handleChange = async file => {
let image

if (file.currentTarget) {
image = file.currentTarget.currentSrc;
console.log(file.currentTarget)
} else {
if (!file.file.url && !file.file.preview) {
file.file.preview = await this.getBase64(file.file.originFileObj);
}
image = file.file.preview;
console.log(file.file)
this.setState({
body: file.file.preview
});
}

console.log(image)

}

handleClientLoad = ()=>{
window.gapi.load('client:auth2', this.initClient);
}

render() {
return (
<div className="App">
<Upload
style={{width: '100%', height: '200px' }}
listType="picture-card"
onChange={this.handleChange} >
<div>
<div style={{ marginTop: 8 }}>Subir imagen</div>
</div>
</Upload>
<div>UserName: <strong>{ this.state.name}</strong></div>
<button id="signin-btn">Sign In</button>
<button id="signout-btn">Sign Out</button>
</div>
);
}
}

export default App;

为什么我的文件损坏了?它说这不是 PNG 文件。将图像上传到驱动器的正确方法是什么?谢谢!!

最佳答案

修改点:

  • 从您的脚本来看,this.state.body 似乎是 base64 数据。这种情况下,需要在请求体的数据头部添加Content-Transfer-Encoding: base64
    • 请注意 multipart/form-data 请求正文的换行符。
  • 当您想使用uploadType=multipart时,请设置multipart/form-data; boundary=### 到标题作为内容类型。在您的脚本中,内容类型似乎是 image/png

当以上几点反射(reflect)到你的脚本中时,它变成如下。

修改后的脚本:

从:
const boundary = '-------314159265358979323846';
const delimiter = "\r\n--" + boundary + "\r\n";
const close_delim = "\r\n--" + boundary + "--";
var fileName='mychat123.png';
var contentType='image/png'
var metadata = {
'name': fileName,
'mimeType': contentType
};

var multipartRequestBody =
delimiter + 'Content-Type: application/json\r\n\r\n' +
JSON.stringify(metadata) +
delimiter +
'Content-Type: ' + contentType + '\r\n';

multipartRequestBody += + '\r\n' + this.state.body;
multipartRequestBody += close_delim;

console.log(multipartRequestBody);
var request = window.gapi.client.request({
'path': 'https://www.googleapis.com/upload/drive/v3/files',
'method': 'POST',
'params': {'uploadType': 'multipart'},
'headers': {
'Content-Type': contentType
},
'body': multipartRequestBody
});
至:
const boundary = '-------314159265358979323846';
const delimiter = "--" + boundary + "\r\n";
const close_delim = "\r\n--" + boundary + "--";
var fileName = 'mychat123.png';
var contentType = 'image/png';
var metadata = {'name': fileName,'mimeType': contentType};
var multipartRequestBody = delimiter +
'Content-Type: application/json\r\n\r\n' +
JSON.stringify(metadata) + "\r\n" +
delimiter +
'Content-Type: ' + contentType + '\r\n' +
'Content-Transfer-Encoding: base64\r\n\r\n' +
this.state.body +
close_delim;
console.log(multipartRequestBody);
var request = window.gapi.client.request({
'path': 'https://www.googleapis.com/upload/drive/v3/files',
'method': 'POST',
'params': {'uploadType': 'multipart'},
'headers': {'Content-Type': 'multipart/form-data; boundary=' + boundary},
'body': multipartRequestBody
});
  • 在Drive API的上传中,目前看来multipart/form-datamultipart/related都可以使用。

备注:

  • 在此答案中,假设您的访问 token 可用于将文件上传到 Google 云端硬盘。请注意这一点。

引用:

添加:

从您的回复中,我注意到您想使用 fetch 而不是 gapi.client.request。在这种情况下,示例脚本如下。

这是您评论中的脚本。

const fd = new FormData();
fd.append("file", this.state.body);
fd.append("title", 'test.png');
const options = {
method: 'POST',
headers: { Authorization: "Bearer" + " " + window.gapi.auth.getToken().access_token },
body: fd
};
await fetch("googleapis.com/upload/drive/v3/files", options)
.then(response => response.json())
.then(jsonResp => { console.log(jsonResp) });

修改点:

  • 在 Drive API v3 中,设置文件名的属性是 name
  • uploadType=multipart 需要在端点中使用。
  • 需要将 base64 数据转换为 blob。

当以上几点反射(reflect)到你的脚本中时,它变成如下。

示例脚本:

// Reference: https://stackoverflow.com/a/16245768
// This method converts from base64 data to blob.
const b64toBlob = (b64Data, contentType='', sliceSize=512) => {
const byteCharacters = atob(b64Data);
const byteArrays = [];

for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);

const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}

const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}

const blob = new Blob(byteArrays, {type: contentType});
return blob;
}

const metadata = {name: 'test.png'};
const fd = new FormData();
fd.append('metadata', new Blob([JSON.stringify(metadata)], {type: 'application/json'}));
fd.append('file', b64toBlob(this.state.body, "image/png"));
fetch('https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart', {
method: 'POST',
headers: {Authorization: 'Bearer ' + window.gapi.auth.getToken().access_token},
body: fd
})
.then(response => response.json())
.then(jsonResp => { console.log(jsonResp) });

关于reactjs - 如何使用 gapi 将图像上传到谷歌驱动器并使用react,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64741113/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com