一、 URL编码的原理
当 URL 路径或者查询参数中,带有中文或者特殊字符的时候,就需要对 URL 进行编码(采用十六进制编码格式)。URL 编码的原则是使用安全字符去表示那些不安全的字符。(安全字符,指的是没有特殊用途或者特殊意义的字符。)
URL 中规定了一些具有特殊意义的字符,常被用来分隔两个不同的 URL 组件,这些字符被称为保留字符。例如:
冒号:用于分隔协议和主机组件,斜杠用于分隔主机和路径
?:用于分隔路径和查询参数等。
=用于表示查询参数中的键值对。
&符号用于分隔查询多个键值对。
其余常用的保留字符有:/ . … # @ $ + ; %
URL 之所以需要编码,是因为 URL 中的某些字符会引起歧义,比如 URL 查询参数中包含了”&”或者”%”就会造成服务器解析错误;再比如,URL 的编码格式采用的是 ASCII 码而非 Unicode 格式,这表明 URL 中不允许包含任何非 ASCII 字符(比如中文),否则就会造成 URL 解析错误。
URL 编码协议规定(RFC3986 协议):URL 中只允许使用 ASCII 字符集可以显示的字符,比如英文字母、数字、和- _ . ~ ! *这 6 个特殊字符。当在 URL 中使用不属于 ASCII 字符集的字符时,就要使用特殊的符号对该字符进行编码,比如空格需要用%20来表示。
除了无法显示的字符需要编码外,还需要对 URL 中的部分保留字符和不安全字符进行编码。
二、 URL编码对照表
三、 代码实现
Controller:
package com.sducsrp.csrp.controller.ToolsController.urlEncode;
import com.sducsrp.csrp.common.Constants;
import com.sducsrp.csrp.common.Result;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.io.UnsupportedEncodingException;
@RestController
public class urlEncodeController {
@RequestMapping("tools/URL/encode")
public @ResponseBody
Result encode(@RequestParam("data") String data) {
System.out.println(data);
String encodeData = null;
encodeData = getURLEncoderString(data);
System.out.println(encodeData);
Result res = new Result(Constants.CODE_200, null, encodeData);
return res;
}
@RequestMapping("tools/URL/decode")
public @ResponseBody
Result decode(@RequestParam("encodeData") String encodeData) {
System.out.println(encodeData);
String data = null;
data = URLDecoderString(encodeData);
Result res = new Result(Constants.CODE_200, null, data);
return res;
}
//URL编码
public static String getURLEncoderString(String str) {
String result = "";
if (null == str) {
return "";
}
try {
result = java.net.URLEncoder.encode(str, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
//URL解码
public static String URLDecoderString(String str) {
String result = "";
if (null == str) {
return "";
}
try {
result = java.net.URLDecoder.decode(str, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
}
vue前端:
<template>
<br><br>
<el-card shadow="always" style="text-align: center; margin-right: 100px;margin-left: 100px;height: 600px">
<el-row>
<el-col :span="8">
<!-- <el-divider style="width:200px;"/>-->
</el-col>
<el-col :span="8">
<!-- <p style="font-size: x-large;color:darkgreen;text-align: right">-->
<!-- -->
<!-- </p>-->
<div style="font-size: x-large;background-color: darkgreen;color:white;margin: 5px;">
URL在线编码解码
</div>
<el-button style="text-align: right" size="small" icon="el-icon-thumb">
<el-link href="https://blog.youkuaiyun.com/ccc369639963/article/details/123398268"
target="_blank"
style="font-size: 20px;color: darkgreen"
>URL编码解码是个啥?
</el-link>
</el-button>
</el-col>
<el-col :span="8">
<!-- <el-divider style="width:200px;"/>-->
</el-col>
</el-row>
<br>
<div id="building" />
<div class="el-common-layout">
<div class="text-area" >
<!-- <textarea v-model="textdata" placeholder="请输入编码字符串或待解码字符串">-->
<!-- </textarea>-->
<el-input
v-model="textdata"
type="textarea"
placeholder="Please input"
style="width: 700px;font-size: 20px"
:rows=5
/>
</div>
</div>
<el-button @click="encode" type="info" style="margin-top:20px ;">EnCode</el-button>
<el-button @click="decode" type="info" >DeCode</el-button>
<el-card style="width: 40%;height: 200px;margin-left: 30%;margin-top: 20px;">
<p style="text-align: left">编码/解码结果:</p>
<p>{{ myresult }}</p>
</el-card>
</el-card>
</template>
<script>
import request from "@/utils/request";
export default {
data(){
return {
textdata: '',
myresult: '',
}
},
methods:{
encode() {
request.get("tools/URL/encode",{
params:{
data:this.textdata
}
}).then(res=>{
this.myresult=res.data
})
},
decode() {
request.get("tools/URL/decode",{
params:{
data:this.textdata
}
}).then(res=>{
this.myresult=res.data
})
}
}
}
</script>
<style scoped>
/*文本域*/
.text-area {
width: 100%;
/*border-top: 1px solid gainsboro;*/
/*border-bottom: 1px solid gainsboro;*/
}
.text-area textarea {
width: 50%;
height: 100%;
/*margin: 0.75rem 0.75rem;*/
/*border: none;*/
/*!*outline: none;*!*/
/*padding-left: 1.125rem;*/
height: 10.5rem;
}
.text-area textarea::-webkit-input-placeholder {
color: #9E9E9E;
}
#app{
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 0px;
}
.body{
margin: 0;
border: 0;
padding: 0;
}
#building{
background: url("/vue/dist/img/jhk-1653394468335.png");
position: fixed;
width: 2500px;
height: 2500px;
background-size: 100%,100%;
}
</style>