我使用打字稿+装饰器+正则表达式的解决方案
const removeTag = new RegExp("(<[a-zA-Z0-9]+>)|(</[a-zA-Z0-9]+>)", "g");
return value.replace(removeTag, "");
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
function filter(target) {
return class extends target {
constructor(...args) {
super(...args);
}
setState(opts) {
const state = {
username: this.filter(opts.username),
password: this.filter(opts.password),
};
super.setState(state);
}
filter(value) {
const removeTag = new RegExp("(<[a-zA-Z0-9]+>)|(</[a-zA-Z0-9]+>)", "g");
return value.replace(removeTag, "");
}
};
}
let Form = class Form {
constructor() {
this.state = {
username: "",
password: "",
};
}
setState(opts) {
this.state = {
...this.state,
...opts,
};
}
getState() {
return this.state;
}
};
Form = __decorate([
filter,
__metadata("design:paramtypes", [])
], Form);
function getElement(key) {
return document.getElementById(key);
}
const button = getElement("btn");
const username = getElement("username");
const password = getElement("password");
const usernameOutput = getElement("username-output");
const passwordOutput = getElement("password-output");
function handleClick() {
const form = new Form();
form.setState({ username: username.value, password: password.value });
usernameOutput.innerHTML = `Username: ${form.getState().username}`;
passwordOutput.innerHTML = `Password: ${form.getState().password}`;
}
button.onclick = handleClick;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
:root {
--bg: #1d1907;
--foreground: #e3e0cd;
--primary: #cfb53b;
--black: #333;
--white: #fafafa;
}
@keyframes borderColor {
from {
border-bottom: 1px solid var(--foreground);
}
to {
border-bottom: 1px solid var(--primary);
}
}
* {
outline: none;
border: none;
}
body {
padding: 0.5rem;
font-family: "Fira Code";
background-color: var(--bg);
color: var(--foreground);
}
input {
border-bottom: 1px solid var(--foreground);
background-color: var(--black);
color: var(--foreground);
padding: 0.5rem;
}
input:focus {
animation-name: borderColor;
animation-duration: 3s;
animation-fill-mode: forwards;
}
button {
padding: 0.5rem;
border-radius: 3px;
border: 1px solid var(--primary);
background-color: var(--primary);
color: var(--white);
}
button:hover,
button:active {
background-color: var(--white);
color: var(--primary);
}
.form {
margin-bottom: 2rem;
}
</style>
<title>Decorator</title>
</head>
<body>
<h1>Prevent Injection</h1>
<div class="form">
<div class="form-group">
<label for="username">Username</label>
<input type="text" id="username" placeholder="Type your username" />
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" placeholder="Type your password" />
</div>
<div class="form-group">
<button id="btn">Enviar</button>
</div>
</div>
<div class="form-result">
<p id="username-output">Username:</p>
<p id="password-output">Password:</p>
</div>
<script src="/dist/pratica1.js"></script>
</body>
</html>
打字稿代码如下:
type State = {
username: string;
password: string;
};
function filter<T extends new (...args: any[]) => any>(target: T): T {
return class extends target {
constructor(...args: any[]) {
super(...args);
}
setState(opts: State) {
const state = {
username: this.filter(opts.username),
password: this.filter(opts.password),
};
super.setState(state);
}
filter(value: string) {
const removeTag = new RegExp("(<[a-zA-Z0-9]+>)|(</[a-zA-Z0-9]+>)", "g");
return value.replace(removeTag, "");
}
};
}
@filter
class Form {
private state: State;
constructor() {
this.state = {
username: "",
password: "",
};
}
setState(opts: State) {
this.state = {
...this.state,
...opts,
};
}
getState() {
return this.state;
}
}
function getElement(key: string): HTMLElement | null {
return document.getElementById(key);
}
const button = getElement("btn") as HTMLButtonElement;
const username = getElement("username") as HTMLInputElement;
const password = getElement("password") as HTMLInputElement;
const usernameOutput = getElement("username-output") as HTMLParagraphElement;
const passwordOutput = getElement("password-output") as HTMLParagraphElement;
function handleClick() {
const form = new Form();
form.setState({ username: username.value, password: password.value });
usernameOutput.innerHTML = `Username: ${form.getState().username}`;
passwordOutput.innerHTML = `Password: ${form.getState().password}`;
}
button.onclick = handleClick;