[英]React.js, Express.js and the dreaded CORS
我很抱歉發布另一個關於 CORS 的問題,但我就是想不通這個問題。
我有一個使用 Express.js 服務器(在http://localhost:9001
上運行)將圖像上傳到 Google Cloud 存儲桶的 React 應用程序。 即使圖像已成功上傳,我仍不斷收到 CORS 錯誤,這使我無法返回圖像的 URL。 即使圖像已上傳,我也不太明白如何得到 CORS 錯誤,但這就是正在發生的事情。
我在谷歌雲存儲桶上配置了 CORS 如下:
[
{
"origin": ["http://localhost:3000"],
"responseHeader": "*",
"method": ["POST"],
"maxAgeSeconds": 3600
}
]
當我檢查 CORS 錯誤時,我看到以下內容:
原點是http://localhost:3000
,所以配置正確,我正在使用POST
上傳圖像,因此也應該允許。
我寫的上傳圖片的function如下:
function postImage(file) {
const formData = new FormData();
formData.append('file', file);
fetch(`${window.location.protocol}//${window.location.hostname}:9001/uploads`, {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
// headers: {
// 'Content-Type': 'multipart/form-data'
// },
body: formData
})
// .then((response) => response.json())
.then((response) => console.log('This is your data:', response.data))
.catch(error => {
console.error('There has been a problem uploading your image', error);
});
}
我已將標頭注釋掉,因為它們不斷拋出Multipart: Boundary not found
錯誤,我已經看到其他人對此有疑問,並且刪除標頭設置並沒有引起任何其他問題。
我在將圖像上傳到 Google Cloud 存儲桶的 Express 服務器上有一個助手 function:
const uploadImage = (file) => new Promise((resolve, reject) => {
const { originalname, buffer } = file
const blob = bucket.file(originalname.replace(/ /g, "_"))
const filetype = blob.name.split('.').pop()
const filename = `${uuidv4()}.${filetype}`
const blobStream = blob.createWriteStream({
resumable: false
})
blobStream.on('finish', () => {
const publicUrl = format(
`https://storage.googleapis.com/${bucket.name}/${filename}`
)
resolve(publicUrl)
})
.on('error', () => {
reject(`Unable to upload image, something went wrong`)
})
.end(buffer)
})
以下是我的 Express 服務器上的功能:
import { typeDefs } from './graphql-schema'
import { ApolloServer } from 'apollo-server-express'
import express from 'express'
import neo4j from 'neo4j-driver'
import { makeAugmentedSchema } from 'neo4j-graphql-js'
import dotenv from 'dotenv'
import { initializeDatabase } from './initialize'
const bodyParser = require('body-parser')
const multer = require('multer')
const uploadImage = require('./helpers/helpers')
dotenv.config()
const app = express()
const schema = makeAugmentedSchema({
typeDefs,
config: {
query: {
exclude: ['RatingCount'],
},
mutation: {
exclude: ['RatingCount'],
},
},
})
const driver = neo4j.driver(
process.env.NEO4J_URI,
neo4j.auth.basic(
process.env.NEO4J_USER,
process.env.NEO4J_PASSWORD
),
{
encrypted: process.env.NEO4J_ENCRYPTED ? 'ENCRYPTION_ON' : 'ENCRYPTION_OFF',
}
)
const init = async (driver) => {
await initializeDatabase(driver)
}
init(driver)
const server = new ApolloServer({
context: { driver, neo4jDatabase: process.env.NEO4J_DATABASE },
schema: schema,
introspection: true,
playground: true,
})
// Specify host, port and path for GraphQL endpoint
const port = process.env.GRAPHQL_SERVER_PORT || 4001
const path = process.env.GRAPHQL_SERVER_PATH || '/graphql'
const host = process.env.GRAPHQL_SERVER_HOST || '0.0.0.0'
// Code for uploading files to Google Cloud
app.use((req, res, next, err) => {
console.error(err.stack)
res.header("Access-Control-Allow-Origin", "*");
res.type('multipart/form-data')
res.status(500).json({
error: err,
message: 'Internal server error!',
})
next()
})
const multerMid = multer({
storage: multer.memoryStorage(),
limits: {
// no larger than 5mb.
fileSize: 5 * 1024 * 1024,
},
})
app.disable('x-powered-by')
app.use(multerMid.single('file'))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false }))
app.post('/uploads', async (req, res, next) => {
try {
const myFile = req.file
const imageUrl = await uploadImage(myFile)
res
.status(200)
.json({
message: "Upload was successful",
data: imageUrl
})
} catch (error) {
next(error)
}
})
server.applyMiddleware({ app, path })
app.listen({ host, port, path }, () => {
console.log(`GraphQL server ready at http://${host}:${port}${path}`)
})
app.listen(9001, () => {
console.log('Node.js -> GCP server now listening for requests!')
})
我已經嘗試了很多不同的方法來讓它工作:
"*"
打開所有來源[here][3]
盡管如此,我仍然收到 CORS 錯誤,但我的上傳仍在工作。 我只需要清除錯誤,就可以獲得返回的圖像 URL。
您將 cors 添加到 Google Cloud 存儲桶,但您忘記將其添加到快遞服務器 POST function。 或者在您的快遞服務器上將其用作全局。
在您的快遞 POST function 上試試這個:
res.header("Access-Control-Allow-Origin", "http://example.com");
或者
res.header("Access-Control-Allow-Origin", "*");
甚至更好:
/* Headers */
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*"); // update to match the domain you will make the request from
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.