目录
▐ 同步请求
之前在网页中通过超链接或者表单就可以向后端发送请求,后端也可以正常响应内容,但当网页与后端交互时,前端不能再进行其他操作,服务器端响应回来的内容会把整个浏览器中的内容覆盖掉,这种请求方式称为同步请求。
➱ 我们以注册为例,同样,在前端html文件中创建一个表单
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
function checkAccount(account){
location.href = "http://127.0.0.1:8088/stuServer/reg?account="+account;
}
</script>
</head>
<body>
账号:<input type="text" name="account" onblur="checkAccount(this.value)" /><span id="msg"></span>
<br />
密码:<input type="password" />
<br />
<input type="submit" value="注册" />
</body>
</html>
➱ 在后端创建对应的Servlet,并在web.xml中配置Servlet
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class RegServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String account = req.getParameter("account");
PrintWriter writer = resp.getWriter();
if (account.equals("123")){
writer.write("账号已存在");
}else {
writer.write("此账号未被注册可以使用");
}
}
}
<servlet>
<servlet-name>reg</servlet-name>
<servlet-class>stuServer.web.RegServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>reg</servlet-name>
<url-pattern>/reg</url-pattern>
</servlet-mapping>
我们可以看到同步请求响应的结果会将浏览器原本的注册界面覆盖掉
这种请求方式在前后端交互时显得很不友好,现在的前后端交互请求都使用的是异步请求。
▐ 异步请求
同时可以做多件事情,前端与服务器交互时,不影响前端网页其他操作。
异步请求是使用js中提供的XMLHtttpRequest对象实现发送异步请求和接受服务器响应的。
➱ 由于同步请求和异步请求属于前端问题,所以我们只需在此案例的前端代码处做出修改即可,后端Servlet代码不变。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
function checkAccount(account){
//同步请求已经被抛弃
//location.href = "http://127.0.0.1:8088/stuServer/reg?account="+account;
//异步请求,使用js对象发送请求
var httpobj = new XMLHttpRequest();
//封装请求地址和数据
httpobj.open("get","http://127.0.0.1:8088/stuServer/reg?account="+account,true);
//发送请求
httpobj.send();
//接收请求
httpobj.onreadystatechange=function(){
document.getElementById("msg").innerHTML = httpobj.responseText;//获取到响应的内容
}
}
</script>
</head>
<body>
账号:<input type="text" name="account" onblur="checkAccount(this.value)" /><span id="msg"></span>
<br />
密码:<input type="password" />
<br />
<input type="submit" value="注册" />
</body>
</html>
但是我们会发现这样做之后还是不能实现我们想要的结果,浏览器会报错,这个错也就是接下来将要提到的跨域问题 。
跨域问题
异步请求时,会出现跨域访问问题:浏览器默认不允许js对象接收来自其他服务器响应的内容,跨域问题是一个前端问题,既可以在前端解决,也可以在后端解决。
▐ 什么是跨域?
• 跨域是指从一个域名的网页去请求另一个域名的资源。
• 比如从 www.baidu.com页面去请求 www.google.com 的资源。但是一般情况下不能这么做,它是由浏览器的同源策略 造成的,是浏览器对 JavaScript 施加的安全限制。
• 跨域的严格一点的定义是:只要协议,域名,端口有任何一个的不同,就被当作是跨域。
• 所谓同源是指:域名,协议,端口均相同,只要有一个不同,就是跨域。
▐ 为什么要跨域访问?
由于现在的前后端分离开发,前端和后端各自在不同的服务站,同一家公司不同项目之间要交互,比如一个location.company.com,而应用是放在app.company.com,这时想从app.company.com去访问location.company.com的资源就属于跨域。
▐ 浏览器为什么要阻止跨域访问?
为了安全,不能让其他服务器的内容肆意的响应到自己的服务中
▐ 如何解决跨域问题?
可以在前端解决,也可以在后端解决,这里我将以后端为例解决(毕竟我是后端程序员哈哈哈)
后端解决就是在响应时,告知浏览器允许来自于某些指定服务响应的内容,让浏览器认为其是安全可靠的。
➱具体操作如下:
在后端添加一个过滤器,这样后端在向前端响应时,告诉浏览器我们本次响应是安全的
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter(urlPatterns = "/*")
public class CorsFilter implements Filter {
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
//允许携带Cookie时不能设置为* 否则前端报错
httpResponse.setHeader("Access-Control-Allow-Origin", httpRequest.getHeader("origin"));//允许所有请求跨域
httpResponse.setHeader("Access-Control-Allow-Methods", "*");//允许跨域的请求方法GET, POST, HEAD 等
httpResponse.setHeader("Access-Control-Allow-Headers", "*");//允许跨域的请求头
httpResponse.setHeader("Access-Control-Allow-Credentials", "true");//是否携带cookie
filterChain.doFilter(servletRequest, servletResponse);
}
}
解决跨域问题后,就可以通过异步请求来达到我们想要的效果了
▐ Axios框架
异步请求的原始写法比较复杂,所以我们通过Axios框架来封装简化这部分代码
axios中文网|axios API 中文文档 | axios
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/axios.min.js"></script>
<script>
function checkAccount(account){
axios.get("http://127.0.0.1:8088/stuServer/reg?account="+account).then(function(resp){
if(resp.status==200){
document.getElementById("msg").innerHTML=resp.data;
}
})
}
</script>
</head>
<body>
账号:<input type="text" name="account" onblur="checkAccount(this.value)" /><span id="msg"></span>
<br />
密码:<input type="password" />
<br />
<input type="submit" value="注册" />
</body>
</html>
▐ 结语
本次的分享就到此为止了,希望我的分享能给您带来帮助,创作不易也欢迎大家三连支持,你们的点赞就是博主更新最大的动力!
如有不同意见,欢迎评论区积极讨论交流,让我们一起学习进步!
有相关问题也可以私信博主,评论区和私信都会认真查看的,我们下次再见
海漫浩浩,我亦苦作舟!大家一起学习,一起进步! 本人微信:g2279605572