elunez/eladmin · error · BadRequestException
外链必须以http://或者https://开头
Error message
外链必须以http://或者https://开头
What it means
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.
Source
Thrown at eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/MenuServiceImpl.java:136
}
@Override
@Transactional(rollbackFor = Exception.class)
public void create(Menu resources) {
if(menuRepository.findByTitle(resources.getTitle()) != null){
throw new EntityExistException(Menu.class,"title",resources.getTitle());
}
if(StringUtils.isNotBlank(resources.getComponentName())){
if(menuRepository.findByComponentName(resources.getComponentName()) != null){
throw new EntityExistException(Menu.class,"componentName",resources.getComponentName());
}
}
if (Long.valueOf(0L).equals(resources.getPid())) {
resources.setPid(null);
}
if(resources.getIFrame()){
if (!(resources.getPath().toLowerCase().startsWith(HTTP_PRE)||resources.getPath().toLowerCase().startsWith(HTTPS_PRE))) {
throw new BadRequestException(BAD_REQUEST);
}
}
menuRepository.save(resources);
// 计算子节点数目
resources.setSubCount(0);
// 更新父节点菜单数目
updateSubCnt(resources.getPid());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(Menu resources) {
if(resources.getId().equals(resources.getPid())) {
throw new BadRequestException("上级不能为自己");
}
Menu menu = menuRepository.findById(resources.getId()).orElseGet(Menu::new);
ValidationUtil.isNull(menu.getId(),"Permission","id",resources.getId());
View on GitHub (pinned to 55fbf70595)
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.
Example fix
// before
menu.setIFrame(true);
menu.setPath("www.example.com/docs"); // rejected
// after
menu.setIFrame(true);
menu.setPath("https://www.example.com/docs"); Defensive patterns
Strategy: validation
Validate before calling
if (menu.getIFrame() && !menu.getPath().toLowerCase().matches("^https?://.*")) {
throw new IllegalArgumentException("外链必须以 http:// 或 https:// 开头");
} Type guard
const isAbsoluteUrl = (p: string) => /^https?:\/\//i.test(p);
Prevention
- 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
When it happens
Trigger: POST /api/menus with iFrame=true and path like 'www.baidu.com' or '/external/doc' — anything not prefixed with http:// or https://.
Common situations: Admins entering a bare domain without the scheme; UI form allowing relative paths for iframe menus; data migrations that stored trimmed URLs.
Related errors
- 上级不能为自己
- 没有这个选项
- A new menu cannot already have an ID
- Menu with title {} existed
- Menu with componentName {} existed
AI-assisted analysis of elunez/eladmin@55fbf70595 (2026-08-14).
Data as JSON: /api/errors/613ded76e9533386.
Report an issue: GitHub.