{"record":{"id":"613ded76e9533386","repo":"elunez/eladmin","slug":"http-https","errorCode":null,"errorMessage":"外链必须以http://或者https://开头","messagePattern":"外链必须以http://或者https://开头","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/MenuServiceImpl.java","lineNumber":136,"sourceCode":"    }\n\n    @Override\n    @Transactional(rollbackFor = Exception.class)\n    public void create(Menu resources) {\n        if(menuRepository.findByTitle(resources.getTitle()) != null){\n            throw new EntityExistException(Menu.class,\"title\",resources.getTitle());\n        }\n        if(StringUtils.isNotBlank(resources.getComponentName())){\n            if(menuRepository.findByComponentName(resources.getComponentName()) != null){\n                throw new EntityExistException(Menu.class,\"componentName\",resources.getComponentName());\n            }\n        }\n        if (Long.valueOf(0L).equals(resources.getPid())) {\n            resources.setPid(null);\n        }\n        if(resources.getIFrame()){\n            if (!(resources.getPath().toLowerCase().startsWith(HTTP_PRE)||resources.getPath().toLowerCase().startsWith(HTTPS_PRE))) {\n                throw new BadRequestException(BAD_REQUEST);\n            }\n        }\n        menuRepository.save(resources);\n        // 计算子节点数目\n        resources.setSubCount(0);\n        // 更新父节点菜单数目\n        updateSubCnt(resources.getPid());\n    }\n\n    @Override\n    @Transactional(rollbackFor = Exception.class)\n    public void update(Menu resources) {\n        if(resources.getId().equals(resources.getPid())) {\n            throw new BadRequestException(\"上级不能为自己\");\n        }\n        Menu menu = menuRepository.findById(resources.getId()).orElseGet(Menu::new);\n        ValidationUtil.isNull(menu.getId(),\"Permission\",\"id\",resources.getId());\n","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/elunez/eladmin/blob/55fbf705956949697dbd68bf9003776609d3d029/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/MenuServiceImpl.java#L118-L154","documentation":"BadRequestException thrown in MenuServiceImpl.create when a menu is flagged as an external link (iFrame = true) but its path does not start with http:// or https:// (case-insensitive). External-link menus are rendered in an iframe, so the path must be an absolute URL. The generic BAD_REQUEST constant is the message, while the Chinese literal '外链必须以http://或者https://开头' documents the rule.","triggerScenarios":"POST /api/menus with iFrame=true and path like 'www.baidu.com' or '/external/doc' — anything not prefixed with http:// or https://.","commonSituations":"Admins entering a bare domain without the scheme; UI form allowing relative paths for iframe menus; data migrations that stored trimmed URLs.","solutions":["Set the menu path to a full URL, e.g. 'https://www.baidu.com' instead of 'www.baidu.com'.","In the front-end form, normalize the input: prepend 'https://' when the user omitted the scheme for iframe menus.","If the target is an internal Vue page, set iFrame=false and use a relative path/component instead."],"exampleFix":"// before\nmenu.setIFrame(true);\nmenu.setPath(\"www.example.com/docs\"); // rejected\n\n// after\nmenu.setIFrame(true);\nmenu.setPath(\"https://www.example.com/docs\");","handlingStrategy":"validation","validationCode":"if (menu.getIFrame() && !menu.getPath().toLowerCase().matches(\"^https?://.*\")) {\n    throw new IllegalArgumentException(\"外链必须以 http:// 或 https:// 开头\");\n}","typeGuard":"const isAbsoluteUrl = (p: string) => /^https?:\\/\\//i.test(p);","tryCatchPattern":null,"preventionTips":["Front-end rule: when the iframe checkbox is on, require the path to match ^https?://","Auto-prepend https:// when the user omits the scheme","Use a URL input component for iframe menu paths"],"tags":["eladmin","menu","iframe","url-validation","bad-request"],"backgroundTag":null,"analyzedSha":"55fbf705956949697dbd68bf9003776609d3d029","analyzedAt":"2026-08-14T11:56:12.758Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}