使用 Axios 上传文件时出现 JavaScript CORS 错误

Posted

技术标签:

【中文标题】使用 Axios 上传文件时出现 JavaScript CORS 错误【英文标题】:JavaScript CORS error when uploading files with Axios 【发布时间】:2020-08-07 11:50:27 【问题描述】:

我正在开发一个 Web 应用程序,后端使用 Flask,前端使用 React 和 Redux。 我想向个人资料页面添加“更改个人资料图片”选项,但每当我使用 axios 向我的/api/user/upload_image/ 路由发出帖子请求时,我都会收到以下错误:

Access to XMLHttpRequest at 'http://localhost:5000/api/user/update_image' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
PATCH http://localhost:5000/api/user/update_image net::ERR_FAILED

这很奇怪,因为我在我的 Flask 应用程序中设置了我的 CORS 包装器,如下所示:

self.cors = CORS(self.app, resources=r"/api/*": "origins": "*")

这应该允许来自所有来源的 /api/ 请求。

我也尝试用 Postman 做同样的事情,它就像一个魅力 - 上传文件并将其保存到 /server/public/profile_pictures/

当我尝试从我的 react 应用程序上传常规 JSON 文本时,它也可以正常工作。它仅在文件上传时出错。

这是用于输入的 JSX + 事件处理程序

<label>
    Change Profile Picture
    <input onChange=(e) => 
        this.setState(image: e.target.files[0])
     type="file" name="image" />
</label>

然后我有一个提交按钮,它以this.state.image 作为参数调度以下操作:

export const updateImage = (file) => 
return async (dispatch, getState) => 
    const formData = 
        user_id: getState().currentUser.user.user_id,
        auth_key: getState().currentUser.auth_key,
        image: file
    
    Axios.patch("http://localhost:5000/api/user/update_image", formData, 
        headers: 
            'Content-Type' : 'multipart/form-data'
        
    )
    .then(response => 
        dispatch(type: UPDATE_IMAGE, payload: response.data)
    )

我也尝试使用内置的 formData 方法来创建 JS 对象,但这也不好。

最后是在/api/user/update_image路由被命中时调用的python方法:

def update_image(self, request):   
    image = request.files['image']
    data = request.params

    image.save("./public/profile_pictures/user_p_picture_id_"+data['user_id']+".jpg")
    fsql.update("""UPDATE users SET profile_picture = %s WHERE user_id = %s""", ("/public/profile_pictures/user_p_picture_id_"+data['user_id']+".jpg", data['user_id']))

    return jsonify(
        "error_code" : "200", 
        "error_message" : "Success"
    ) 

【问题讨论】:

【参考方案1】:

我实际上在大约一个半星期前解决了这个问题,但我今天检查了状态。

所以解决方案是对我的配置参数和 CORS 参数进行一些更改。这是我现在使用的配置:

config = 
    'ORIGINS': [
        'http://localhost:3000',  # React
        'http://127.0.0.1:3000',  # React
    ],
    'SECRET_KEY': '...' #secret key

    self.cors = CORS(self.app, resources=
        r'/api/*': 
            "Access-Control-Allow-Origin": config["ORIGINS"],
            "Access-Control-Allow-Credentials": True,
            'supports_credentials': True
        ,
    ,
    supports_credentials = True,
    expose_headers = "*"
)

self.app.config['UPLOAD_FOLDER'] = r'/*' # Change this to only the folder you want to save images to
self.app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # Change this according to your file size

这解决了我的 CORS 和文件传输问题。

我真的希望这对某人有所帮助。 flask-cors 上的 CORS 文档并未涵盖有关文件上传和会话存储的所有内容,因此我们不得不在不知道所有工作原理的情况下解决错误 - 就像尝试解决丢失部分的难题一样。

如果您在烧瓶中有任何用于 CORS 的好工具,并且有良好的文档记录并且周围有社区,请在消息中添加 HMU。

【讨论】:

以上是关于使用 Axios 上传文件时出现 JavaScript CORS 错误的主要内容,如果未能解决你的问题,请参考以下文章

通过axios发送文件时出现500错误

进行 axios.get 调用时出现 CORS 错误

为什么在提交表单时出现500错误?

为啥我使用 axios 获取数据时出现错误 500

使用 Axios 和 Firebase 时出现 401 未经授权的错误

使用 axios 发出请求时出现 MethodNotAllowedHttpException(流明)