Request header field sessionId is not allowed by Access-Control-Allow-Headers in preflight response.

本文介绍了一种解决跨域请求异常的方法,特别是在上传图片时遇到的问题:Request header field sessionId is not allowed by Access-Control-Allow-Headers in preflight response。通过删除并重新设置sessionId来避免跨域错误。

上传图片 跨域请求 出现异常

跨域请求出现异常:Request header field sessionId is not allowed by Access-Control-Allow-Headers in preflight response.

原因:调用的接口,请求头中不允许sessionId
解决方法:在ajax方法调用之前先把设置的sessionId删除,待处理完成之后,也要记得把sessionId设置回去。
删除:
delete jQuery.ajaxSettings.headers['sessionId']

设置回去:
jQuery.ajaxSettings.headers['sessionId'] = Cookies.get("sessionId");

具体案例:
//上传图片功能
        function uploadImg(file) {
            var fd = new FormData();
            fd.append('uploadFile', file);

            //删除请求头中的sessionid
            delete jQuery.ajaxSettings.headers['sessionId']

            $.ajax({
                url:uploadUrl,
                type: "post",
                // Form数据
                dataType:'json',
                data: fd,
                cache: false,
                contentType: false,
                processData: false,
                beforeSend:function(xhr){
                    //删除请求头中的sessionid  这里不一定可以,在本项目中,就不行
                    //  delete jQuery.ajaxSettings.headers['sessionId']
                },
                success: function (data) {
//                jQuery.ajaxSettings.headers['sessionId'] = Cookies.get("sessionId");
                    linkImage = data.visitPath;

                    //上传成功,展示在页面上  展示 linlUrl
                    $("#linkImage").attr("src",linkImage);
                }

            });

            //将数据设置回去
            jQuery.ajaxSettings.headers['sessionId'] = Cookies.get("sessionId");

        }
C:\Users\ASUS\.conda\envs\wys\python.exe C:\Users\ASUS\Desktop\Pro\API\app.py Traceback (most recent call last): File "C:\Users\ASUS\Desktop\Pro\API\app.py", line 188, in <module> if not os.path.exists(app.config['UPLOAD_FOLDER']): KeyError: 'UPLOAD_FOLDER'from flask import Flask, request, jsonify, send_from_directory, make_response from flask_sqlalchemy import SQLAlchemy from flask_cors import CORS from functools import wraps # 新增 import os import uuid from datetime import datetime # 初始化Flask应用 app = Flask(__name__) # ================ CORS全局配置 ================ CORS(app, resources={ r"/*": { "origins": "http://localhost:5173", "methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"], "allow_headers": ["Content-Type", "Authorization", "X-Requested-With"], "supports_credentials": True, "expose_headers": ["Set-Cookie"] # 修改 } }) # ================ 新增认证中间件 ================ def login_required(f): @wraps(f) def decorated_function(*args, **kwargs): # 从cookie获取用户ID user_id = request.cookies.get('user_id') if not user_id: return jsonify({"message": "未认证"}), 401 # 验证用户是否存在 user = User.query.get(user_id) if not user: return jsonify({"message": "用户不存在"}), 401 return f(*args, **kwargs) return decorated_function # ================ 修改登录接口 ================ @app.route('/login', methods=['POST', 'OPTIONS']) def login(): try: if request.method == 'OPTIONS': return _build_cors_preflight_response() data = request.get_json() username = data.get('username', '').strip() password = data.get('password', '') user = User.query.filter_by(username=username).first() if not user or user.password != password: return jsonify({"message": "认证失败"}), 401 # 创建响应并设置cookie response = jsonify({ "message": "登录成功", "user_id": user.id, "profile_completed": user.profile_completed, "avatar_url": f"/uploads/{user.avatar}" }) # 设置HTTP-only Cookie response.set_cookie( key='user_id', value=str(user.id), httponly=True, samesite='Lax', max_age=86400, # 1天有效期 secure=False, # 开发环境关闭 domain='localhost' ) return response, 200 except Exception as e: return jsonify({"message": f"服务器错误: {str(e)}"}), 500 # ================ 修改用户资料接口 ================ @app.route('/user/<int:user_id>', methods=['GET', 'PUT', 'OPTIONS']) @login_required # 新增认证装饰器 def user_profile(user_id): try: if request.method == 'OPTIONS': return _build_cors_preflight_response() # 从cookie获取当前用户 current_user_id = int(request.cookies.get('user_id')) # 验证用户权限 if current_user_id != user_id: return jsonify({"message": "无权访问"}), 403 user = User.query.get_or_404(user_id) if request.method == 'GET': return jsonify({ "username": user.username, "shop_name": user.shop_name, "phone": user.phone, "email": user.email }), 200 if request.method == 'PUT': data = request.get_json() if not data: return jsonify({"message": "请求体不能为空"}), 400 update_fields = { 'shop_name': data.get('shop_name'), 'phone': data.get('phone'), 'email': data.get('email') } for field, value in update_fields.items(): if value is not None and getattr(user, field) != value: setattr(user, field, value) db.session.commit() return jsonify({"message": "更新成功"}), 200 except Exception as e: db.session.rollback() app.logger.error(f"用户资料操作失败: {str(e)}") return jsonify({"message": "服务器错误"}), 500 # ================ 修改密码接口 ================ @app.route('/user/<int:user_id>/password', methods=['PUT', 'OPTIONS']) @login_required # 新增认证装饰器 def update_password(user_id): try: # 权限验证 current_user_id = int(request.cookies.get('user_id')) if current_user_id != user_id: return jsonify({"message": "无权操作"}), 403 user = User.query.get_or_404(user_id) data = request.get_json() if 'old_password' not in data or 'new_password' not in data: return jsonify({"message": "需要提供原密码和新密码"}), 400 if user.password != data['old_password']: return jsonify({"message": "原密码错误"}), 401 if len(data['new_password']) < 6: return jsonify({"message": "密码至少6位"}), 400 user.password = data['new_password'] user.password_updated_at = datetime.utcnow() db.session.commit() return jsonify({"message": "密码更新成功"}), 200 except Exception as e: db.session.rollback() return jsonify({"message": f"服务器错误: {str(e)}"}), 500 # ================ 工具函数 ================ def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in {'png', 'jpg', 'jpeg'} def _build_cors_preflight_response(): response = make_response() response.headers.add("Access-Control-Allow-Origin", "http://localhost:5173") response.headers.add("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With") response.headers.add("Access-Control-Allow-Methods", "*") response.headers.add("Access-Control-Max-Age", "86400") response.headers.add("Access-Control-Allow-Credentials", "true") response.headers['Access-Control-Allow-Origin'] = 'http://localhost:5173' response.headers['Access-Control-Allow-Credentials'] = 'true' response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization' return response, 204 # ================ 启动应用 ================ if __name__ == '__main__': # 确保上传目录存在 if not os.path.exists(app.config['UPLOAD_FOLDER']): os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) # 检查数据库连接 try: with app.app_context(): db.create_all() db.engine.connect() print("✅ 数据库连接成功") except Exception as e: print(f"❌ 数据库连接失败: {str(e)}") exit(1) app.run(host='0.0.0.0', port=5000, debug=True)
05-27
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值