JS实现Html转义和反转义以及解决转义后&被post截断的问题
封装的工具方法
var HtmlUtil = {
/*1.用浏览器内部转换器实现html编码(转义)*/
htmlEncode:function (html){
//1.首先动态创建一个容器标签元素,如DIV
var temp = document.createElement ("div");
//2.然后将要转换的字符串设置为这个元素的innerText或者textContent
(temp.textContent != undefined ) ? (temp.textContent = html) : (temp.innerText = html);
//3.最后返回这个元素的innerHTML,即得到经过HTML编码转换的字符串了
var output = temp.innerHTML;
temp = null;
return output;
},
/*2.用浏览器内部转换器实现html解码(反转义)*/
htmlDecode:function (text){
//1.首先动态创建一个容器标签元素,如DIV
var temp = document.createElement("div");
//2.然后将要转换的字符串设置为这个元素的innerHTML(ie,火狐,google都支持)
temp.innerHTML = text;
//3.最后返回这个元素的innerText或者textContent,即得到经过HTML解码的字符串了。
var output = temp.innerText || temp.textContent;
temp = null;
return output;
},
/*3.用正则表达式实现html编码(转义)*/
htmlEncodeByRegExp:function (str){
var temp = "";
if(str.length == 0) return "";
temp = str.replace(/&/g,"&");
temp = temp.replace(/</g,"<");
temp = temp.replace(/>/g,">");
temp = temp.replace(/\s/g," ");
temp = temp.replace(/\'/g,"'");
temp = temp.replace(/\"/g,""");
return temp;
},
/*4.用正则表达式实现html解码(反转义)*/
htmlDecodeByRegExp:function (str){
var temp = "";
if(str.length == 0) return "";
temp = str.replace(/&/g,"&");
temp = temp.replace(/</g,"<");
temp = temp.replace(/>/g,">");
temp = temp.replace(/ /g," ");
temp = temp.replace(/'/g,"\'");
temp = temp.replace(/"/g,"\"");
return temp;
},
/*5.用正则表达式实现html编码(转义)(另一种写法)*/
html2Escape:function(sHtml) {
return sHtml.replace(/[<>&"]/g,function(c){return {'<':'<','>':'>','&':'&','"':'"'}[c];});
},
/*6.用正则表达式实现html解码(反转义)(另一种写法)*/
escape2Html:function (str) {
var arrEntities={'lt':'<','gt':'>','nbsp':' ','amp':'&','quot':'"'};
return str.replace(/&(lt|gt|nbsp|amp|quot);/ig,function(all,t){return arrEntities[t];});
}
};
其中htmlEncodeByRegExp方法如果使用eslint检测会有些问题,我们可以如下修改(就是直接去掉引号前面的斜杠即可):
/*3.用正则表达式实现html编码(转义)*/
htmlEncodeByRegExp:function (str){
var temp = "";
if(str.length == 0) return "";
temp = str.replace(/&/g,"&");
temp = temp.replace(/</g,"<");
temp = temp.replace(/>/g,">");
temp = temp.replace(/\s/g," ");
/* eslint-disable */
temp = temp.replace(/'/g,"'");
/* eslint-disable */
temp = temp.replace(/"/g,""");
return temp;
},
或者使用eslint排除掉:
/* eslint-disable */
temp = temp.replace(/\'/g,"'");
/* eslint-disable */
temp = temp.replace(/\"/g,""");
关于$_post截取
比如我们有如下html结构:
<a class="lin-banner" href="https://www.wubin.work/"></a>
简单的使用HtmlUtil.htmlEncode(html),会得到如下结果:
<a class="lin-banner" href="https://www.wubin.work/"></a>
然后当我们将这个字符串粗暴的赋值给一个对象属性,并转化为json后直接上传到php服务器,并用$_post接收,会发现无法获取这个字符串的内容。
前端获取表单数据提交时,如果字符串内容是带有参数如?\&等特殊符号的URL时,添加到JSON中会出现被截断的情况,使得最终得到的JSON异常;
在html内容里面难免会包含&这个符号,在提交一个字符串形式的值是,如果你用的是Post方式,他会根据&符号去切割,也就是说 他把这个json对象根据&切割成N份了,所以才会造成被截断。
就是$_post会按照&进行截断,分别获取对应的键-值。因此,如果遇到这种情况,也要对&进行一次变化。
使用PHP进行替换:
$old_url = "http://www.wubin.work/share/?t=1&d=10179";
$new_url = strtr($old_url, '&', '%26');
使用JS简单替换:
// 这个只是简单的替换第一个遇到的&
var str = str.replace("&","%26");
结合上面封装的工具方法,再封装两个针对&进行转义的方法:
// HTML转字符串
export function encodeHtml(html) {
// 再将代码中<>等转义
let htmlCode = HtmlUtil.htmlEncode(html);
// 当字符串中有&时,$_post会按照&截断,所以要替换一下
htmlCode = htmlCode.replace(/&/g,"%26");
return htmlCode;
}
// 字符串转html
export function decodeHtml(htmlCode) {
// 先将&替换回来
let html = htmlCode.replace(/%26/g,"&");
// 再转义为html实体
html = HtmlUtil.htmlDecode(html);
return html;
}
这里使用g,代表替换字符串中所有的&为%26。
【重要】更新于2024-2-1:关于&替换为%26的存入数据库后再被数据库转换为&问题。
当我们在前端,将&转换为%26之后,如下:
%26lt;a class="lin-banner" href="https://www.wubin.work/"%26gt;%26lt;/a%26gt;
然后传到$_post中,也没问题,但是当将含有%26这个字符串存入数据库中时,我发现数据库会自动将%26再转换成&,然后再随着get方法返回到前端中,就又变成了:
<a class="lin-banner" href="https://www.wubin.work/"></a>
当再提交时候,又会被$_post获取截断!所以,最终我的解决思路就是将%26改为%2%6。
在前端转换&的方法:
// HTML转字符串
export function encodeHtml(html) {
// 再将代码中<>等转义
let htmlCode = HtmlUtil.htmlEncode(html);
// 当字符串中有&时,$_post会按照&截断,所以要替换一下
htmlCode = htmlCode.replace(/&/g,"%2%6");
return htmlCode;
}
// 字符串转html
export function decodeHtml(htmlCode) {
// 先将&替换回来
let html = htmlCode.replace(/%2%6/g,"&");
// 再转义为html实体
html = HtmlUtil.htmlDecode(html);
return html;
}
在PHP中,替换字符串中所有的%2%6为&,并将转义字符串转回html结构:
function getCustomHtml($htmlcode='') {
if($htmlcode) {
$htmlcode = str_replace('%2%6', '&', $htmlcode);
$htmlcode = str_replace("\\n", "", $htmlcode);
$htmlcode = htmlspecialchars_decode($htmlcode);
}
return $htmlcode;
}
其他的一些JS处理html字符串的常用方法
去掉字符串中的html标签
function removeHtmlTab(tab) {
return tab.replace(/<[^<>]+?>/g,'');//删除所有HTML标签
}
removeHtmlTab('<div id="test">zyl</div><span>zzc</span>');// zylzzc
回车\r\n转为标签
function return2Br(str) {
return str.replace(/\r?\n/g,"<br />");
}
去除开头结尾换行,并将连续3次以上换行转换成2次换行
function trimBr(str) {
str=str.replace(/((\s| )*\r?\n){3,}/g,"\r\n\r\n");//限制最多2次换行
str=str.replace(/^((\s| )*\r?\n)+/g,'');//清除开头换行
str=str.replace(/((\s| )*\r?\n)+$/g,'');//清除结尾换行
return str;
}
将多个连续空格合并成一个空格
function mergeSpace(str) {
str=str.replace(/(\s| )+/g,' ');
return str;
}