前端文件上传报预检错误OPTIONS请求,前端token无法携带会过拦截器401

拦截器public class AuthInterceptor implements Interceptor {

    @SneakyThrows
    @Override
    public void intercept(Invocation inv) {
        Controller controller = inv.getController();
        String t = controller.getHeader("Authorization");
        if (StringUtils.isBlank(t)) {
            t = controller.getCookie("Authorization", "");
        }
        if (StringUtils.isBlank(t)) {
            // 如果Header和Cookie中都没有找到Token,则直接返回错误
            controller.renderError(401, new JsonRender(Ret.fail().set("msg", "Token未提供").set("code", 401)));
            return;
        }
            String[] str = t.split("/");
        // 提前验证token是否失效
        Record r = Db.findFirst("SELECT * FROM PD_USER WHERE TOKEN=?", t);
        if (null == r) {
            controller.renderError(401, new JsonRender(Ret.fail().set("msg", "用户信息已失效").set("code", 401)));
            return;
        }
路由配置(其中prefi为/api)
        public void configRoute(Routes me) {
   me.add(prefix+ "model",ModelController.class);
}
跨域配置
public class BaseController extends Controller {
   public void setCORS(HttpServletResponse response) {
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600"); // 设置过期时间
    response.setHeader("Access-Control-Allow-Headers","*" );
    response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // 支持HTTP 1.1.
    response.setHeader("Pragma", "no-cache"); // 支持HTTP 1.0. response.setHeader("Expires", "0");
}
}
控制器(走不进来,postman可用)
public class ModelController extends BaseController{
  public void importModel() {
    UploadFile file = getFile("file"); // "file" 是前端上传文件的字段名
    if (file == null) {
        renderJson("status", "error");
        return;
    }
    // 使用 Hutool 读取 Excel 文件
    ExcelReader reader = ExcelUtil.getReader(file.getFile());
    List<List<Object>> data = reader.read(); // 读取所有数据
    // 将数据转换为 JSON 格式
    JSONArray jsonArray = new JSONArray();
    for (int i = 1; i < data.size(); i++) { // 从第二行开始(跳过表头)
        List<Object> row = data.get(i);
        JSONObject jsonObject = new JSONObject();
        // 手动映射字段
        jsonObject.put("PN", row.get(0)); // 第一列 -> name
        jsonObject.put("PN_DESC", row.get(1));  // 第二列 -> age
        jsonObject.put("MAX_MODEL", row.get(2)); // 第三列 -> city
        jsonObject.put("MODEL", row.get(2));
        jsonArray.add(jsonObject);
    }
    // 打印转换后的 JSON 数据
    //System.out.println(jsonArray.toJSONString());
    // 返回成功响应和 JSON 数据
    JSONObject result = new JSONObject();
    result.put("status", "success");
    result.put("modelList", jsonArray);
    renderJson(result);
    try {
        Record user = UserDao.dao.getUserByToken(getHeader("Authorization"));
        result.put("OP_ID", user.getStr("OP_ID"));
        boolean flag = ModelDao.dao.importModel(result);
        renderJson(flag ? Result.success() : Result.error());
    } catch (Exception e) {
        //记录错误消息到日志
        LogKit.error(e.getMessage());
        // TODO: handle exception
        renderJson(Ret.fail().set("code", HttpStatus.ERROR).set("msg", e.getMessage()));
    }
    }
}


评论区

杜福忠

2025-01-12 11:49

跨域配置建议使用CORSInterceptor拦截器:
https://gitee.com/-/ide/project/jfinal/jfinal/edit/master/-/src/main/java/com/jfinal/ext/cors/CORSInterceptor.java

看上图代码 BaseController 的 setCORS 也不知道是何时调用的。
建议直接使用 JF内置的CORSInterceptor处理,需在 AuthInterceptor 之前。

isddoidnoi

2025-01-13 08:41

这样调用的,会先走AuthInterceptor,再走BaseController吗
@Before(AuthInterceptor.class)
public class ModelController extends BaseController{ public void importModel() {
... ...
}
}@杜福忠

杜福忠

2025-01-13 09:20

@isddoidnoi https://jfinal.com/doc/4-2

热门反馈

扫码入社