如何条件激活提交按钮,仅输入合法图片URL时才可提交表单?
前端修改方案
- 新增图片URL校验函数,判断输入内容是否为空、是否符合URL格式、是否为图片资源地址
- 给提交按钮绑定
disabled属性,输入内容不合法时按钮自动置灰不可点击 - 提交逻辑中新增前置校验,避免绕过前端限制的异常提交
修改后的前端代码如下:
import { FormControl, Input, Button } from "@chakra-ui/react"; import axios from "axios"; import React from "react"; import { baseUrl } from "../config"; // 图片URL校验工具函数 const isImageUrl = (url) => { if (!url.trim()) return false; // 基础URL格式校验 const urlPattern = new RegExp('^(https?:\\/\\/)?'+ '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ '((\\d{1,3}\\.){3}\\d{1,3}))'+ '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ '(\\?[;&a-z\\d%_.~+=-]*)?'+ '(\\#[-a-z\\d_]*)?$','i'); if (!urlPattern.test(url)) return false; // 图片后缀校验,可根据需求扩展支持的格式 return /\.(jpg|jpeg|png|gif|webp|svg)$/i.test(url); } class SubmitLink extends React.Component { constructor(props) { super(props); this.state = { url: "", }; } onInputChange = (event) => { this.setState({ url: event.target.value, }); }; onClick = () => { // 前置校验,不合法直接终止提交 if (!isImageUrl(this.state.url)) return; axios .post(`${baseUrl}/submitlink`, { url: this.state.url, }) .then((response) => { console.log(response); this.props.onSuccessfulUpload(); this.setState({ url: "", }); }) .catch(function (error) { console.log(error); }); }; render() { return ( <FormControl> <Input type='url' value={this.state.url} onChange={this.onInputChange} width={{ base: "70%", md: "55%", xl: "60%", }} ml={{ base: "5%", md: "5%", xl: "4%", }} /> <Button ml={2} mb={1} colorScheme='teal' type='submit' onClick={this.onClick} size='md' // 绑定禁用状态 disabled={!isImageUrl(this.state.url)} > 提交 </Button> </FormControl> ); } } export default SubmitLink;
后端修改方案
前端校验只能拦截普通用户的异常操作,必须在后端新增校验逻辑兜底,避免有人直接调用接口提交非法数据。
修改后的后端代码如下:
// 用于保存URL来源图片的POST接口 const imageModel = require("../models/models.js"); // 忽略日期变量,尚未完成正式实现 var date = new Date(); var currentDate = date.toLocaleDateString(); const submitLink = async (req, res) => { const { url } = req.body; // 前置校验逻辑 if (!url?.trim()) { return res.sendStatus(400); } // 和前端一致的URL校验规则 const urlPattern = new RegExp('^(https?:\\/\\/)?'+ '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ '((\\d{1,3}\\.){3}\\d{1,3}))'+ '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ '(\\?[;&a-z\\d%_.~+=-]*)?'+ '(\\#[-a-z\\d_]*)?$','i'); if (!urlPattern.test(url) || !/\.(jpg|jpeg|png|gif|webp|svg)$/i.test(url)) { return res.sendStatus(400); } let saveImageFromUrl = new imageModel(); saveImageFromUrl.img.data = req.body.url; saveImageFromUrl.postedAt = currentDate; await saveImageFromUrl.save(function (err, result) { if (err) return console.error(err); else { res.sendStatus(202); } }); }; module.exports = submitLink;
内容的提问来源于stack exchange,提问作者tanjim anim
相关产品推荐
相关产品推荐

