[英]React.js, Express.js and the dreaded CORS
I'm sorry to be posting yet another question about CORS but I just can't figure this one out.我很抱歉发布另一个关于 CORS 的问题,但我就是想不通这个问题。
I have a React app using an Express.js server (running on http://localhost:9001
) to upload an image to a Google Cloud storage bucket.我有一个使用 Express.js 服务器(在
http://localhost:9001
上运行)将图像上传到 Google Cloud 存储桶的 React 应用程序。 I keep getting a CORS error even though the image is uploaded successfully and this is preventing me from getting the image's URL returned.即使图像已成功上传,我仍不断收到 CORS 错误,这使我无法返回图像的 URL。 I don't really understand how I can get a CORS error even though the image is uploaded but that's what's happening.
即使图像已上传,我也不太明白如何得到 CORS 错误,但这就是正在发生的事情。
I have configured CORS on the Google Cloud storage bucket as follows:我在谷歌云存储桶上配置了 CORS 如下:
[
{
"origin": ["http://localhost:3000"],
"responseHeader": "*",
"method": ["POST"],
"maxAgeSeconds": 3600
}
]
When I inspect the CORS error I'm getting I see the following:当我检查 CORS 错误时,我看到以下内容:
The origin is http://localhost:3000
, so that's configured correctly and I'm using POST
to upload the image so that should be allowed as well.原点是
http://localhost:3000
,所以配置正确,我正在使用POST
上传图像,因此也应该允许。
The function I've written to upload the image is as follows:我写的上传图片的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);
});
}
I've commented out the headers as including them kept throwing up a Multipart: Boundary not found
error that I've seen others have an issue with and removing the headers setting hasn't caused any other issues.我已将标头注释掉,因为它们不断抛出
Multipart: Boundary not found
错误,我已经看到其他人对此有疑问,并且删除标头设置并没有引起任何其他问题。
I have a helper function on the Express server that uploads the image to the Google Cloud storage bucket:我在将图像上传到 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)
})
Here are the functions on my Express server:以下是我的 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!')
})
I've tried a lot of different things to get this working:我已经尝试了很多不同的方法来让它工作:
"*"
for"*"
打开所有来源[here][3]
[here][3]
Despite all of this I'm still getting the CORS error but my upload is still working.尽管如此,我仍然收到 CORS 错误,但我的上传仍在工作。 I just need to clear the error so I can get the returned image URL.
我只需要清除错误,就可以获得返回的图像 URL。
You add cors to Google Cloud storage bucket but you forgot to add it to express server POST function.您将 cors 添加到 Google Cloud 存储桶,但您忘记将其添加到快递服务器 POST function。 Or use it as global on your express server.
或者在您的快递服务器上将其用作全局。
Try this on your express POST function:在您的快递 POST function 上试试这个:
res.header("Access-Control-Allow-Origin", "http://example.com");
Or或者
res.header("Access-Control-Allow-Origin", "*");
Or even better:甚至更好:
/* 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.