如何解决在React JS中将图像/视频文件上传到Google Cloud的CORS错误
当用户拖放图像时,我需要调用服务器的方法来获取该特定图像/视频的Media_id,作为响应,我得到了这个->
主要响应->>
{
"status": 1,"media": {"media_id": 27,"media_type": 1,"media_file_name": "a9989aafcdf1482d8a0967a81b54b476_80a2d60394f15063bef4e44e1a4d83f3.png","media_placeholder": null,"media_ext": "png"},"upload":
{
"upload_url": "https://storage.googleapis.com/fnc-59aa2e6b-71552c9d-6441d628-951a8f6f/l.img/ori/a9989aafcdf1482d8a0967a81b54b476_80a2d60394f15063bef4e44e1a4d83f3.png?Expires=1603388214&GoogleAccessId=12345678-compute%40developer.gserviceaccount.com&Signature=UNt8nS3%2BJYiS4AuYdZ7Z2fvfDZ0fAKf8bSZbeRlHyhqxb5i6xjpqnqgR7JYp9Q3FgJItcYr%2BHDL90WiUpbMQi%2B4s0XNW683CaSoUChkRMjj1AvkH%2Be0u8%2Fw5VVIMF9j52bTFePWISTLvwQ1RlEdNPNkrpbcamTsJFyBVi89%2BIpXArsVlhvDzK55Zvj%2Fvzh00GgdNrH%2BRog8Q%2BkGITE8bW%2FxRpQ30OdMZLjpLtp%2FNg5KVotHrx6Bet7vidKymiJQ9BbwCxTRGzBdAITr2rsKTMGZJzfvEKnIczsoiY91Zmc3hjGzUD9OxHGR%2BiRdN%2F2FbotOIVR48RE%2BoAdIGIEfKlw%3D%3D","file_name": "a9989aafcdf1482d8a0967a81b54b476_80a2d60394f15063bef4e44e1a4d83f3.png","content_type": "image/png","exp": "2020-10-22 17:36:54.447484"
}}
因此,我需要点击响应中的上传网址。下面是我的文件,一旦用户放下图片,我就会立即点击该文件->
UploadImage.js
await this.props.getFirstMediaId(postdata).then(res => {
if (res.value && res.value.status === 1) {
let media_idArr = this.state.media_id.concat(res.value.media.media_id)
this.setState({ media_id: media_idArr,mediaUrl: res.value.upload })
customStatus = 'done';
}
}) //First call to the server to get Media_id and the cloud **upload URL**
***** FOR THIS API RESPONSE,PLEASE SEE THE ABOVE MAIN RESPONSE *****
const getUploadParams = () => {
console.log(this.state.mediaUrl,' -->>> this.state.mediaUrl')
if (this.state.mediaUrl !== null) {
console.log(' in get upload param.')
return this.props.postImageToCloud(this.state.mediaUrl).then(res => {
console.log(res,'===>> here is cloud res.')
})
.catch(err => {
console.log(' here is error cloud -->>> ',err)
})
}
}
下面是该方法实际调用API的文件->
service.js
export const getFirstMediaId = (data) => {
return {
type: GET_FIRST_LISTING_MEDIA,async payload() {
let response = await callAxios.post(SUBMIT_LISTING_FIRST_MEDIA,data);
return objectPath.get(response,'data',[]);
}
}
}
export const postImageToCloud = (url) => {
return {
type: PUT_MEDIA_TO_CLOUD,async payload() {
let response = await axios.put(url.upload_url,{},{
headers: {
'Content-Type': `${url.content_type}`
}
})
return objectPath.get(response,[]);
}
}
}
因此,第一个调用成功,我得到了上面的 MAIN RESPONSE ,但是一旦完成,我就调用了云PUT请求并收到了CORS错误->
访问XMLHttpRequest的地址为https://storage.googleapis.com/fnc-59aa2e6b-71552c9d-6441d628-951a8f6f/l.img/ori/a9989aafcdf1482d8a0967a81b54b476_80a2d60394f15063pngf4e44e1a4d83fc3d-e3e4e3d3d3d0f0f0f9e8e0e0b0e0e0b0e0b0e0b0e0美国COM&签名= UNt8nS3%2BJYiS4AuYdZ7Z2fvfDZ0fAKf8bSZbeRlHyhqxb5i6xjpqnqgR7JYp9Q3FgJItcYr%2BHDL90WiUpbMQi%2B4s0XNW683CaSoUChkRMjj1AvkH%2Be0u8%2Fw5VVIMF9j52bTFePWISTLvwQ1RlEdNPNkrpbcamTsJFyBVi89%2BIpXArsVlhvDzK55Zvj%2Fvzh00GgdNrH%2BRog8Q%2BkGITE8bW%2FxRpQ30OdMZLjpLtp%2FNg5KVotHrx6Bet7vidKymiJQ9BbwCxTRGzBdAITr2rsKTMGZJzfvEKnIczsoiY91Zmc3hjGzUD9OxHGR%2BiRdN%2F2FbotOIVR48RE%2BoAdIGIEfKlw%3D%3D”从原点的 'http://本地主机:8000' 已被封锁根据CORS政策:对预检请求的响应未通过访问控制检查:所请求的资源上不存在“ Access-Control-Allow-Origin”标头。
请给我建议任何使它起作用的方法。 谢谢。
解决方法
最后,经过大量的努力,我知道我必须在PUT请求的主体中传递文件,这里->
let response = await axios.put(url.upload_url,{ **file here** },{
headers: {
'Content-Type': `${url.content_type}`
}
})
但是我尝试使用formData将图像文件对象简单地传递给html文件对象,并按原样传递,仍然遇到相同的错误。然后我开始使用 react-dropzone ,并将图像文件转换为字符串缓冲区,作为React-dropzone中的示例之一。我将在此处粘贴该示例,也许它可以帮助任何人。见下文->
import React,{useCallback} from 'react'
import {useDropzone} from 'react-dropzone'
function MyDropzone() {
const onDrop = useCallback((acceptedFiles) => {
acceptedFiles.forEach((file) => {
const reader = new FileReader()
reader.onabort = () => console.log('file reading was aborted')
reader.onerror = () => console.log('file reading has failed')
reader.onload = () => {
// Do whatever you want with the file contents
const binaryStr = reader.result
console.log(binaryStr)
*****PASS THIS (binaryStr) AS IN THE BODY OF PUT TO AXIOS****
}
reader.readAsArrayBuffer(file)
})
},[])
const {getRootProps,getInputProps} = useDropzone({onDrop})
return (
<div {...getRootProps()}>
<input {...getInputProps()} />
<p>Drag 'n' drop some files here,or click to select files</p>
</div>
)
}
这是React-Dropzone的官方示例之一,因此我只传递了该字符串缓冲区obj,最后它起作用了,没有CORS没有任何问题。
,Google Storage API根本不接受从另一个域中的浏览器发起的请求,因此您将无法实现。
您不应从客户端调用API,而应从后端调用。以下是建议的库列表:https://cloud.google.com/storage/docs/reference/libraries?hl=fr
请注意,不建议在浏览器环境中使用JavaScript(仅使用Node.js)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。