这篇文章主要讲解了“AJAX跨域问题怎么解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“AJAX跨域问题怎么解决”吧!
跨域简单的说,就是从一个域名的网页去访问另一个域名网页的资源。
通过超链接或者form表单提交或者window.location.href的方式进行跨域是不存在问题的。但在一个域名的网页中的一段js代码发送ajax请求去访问另一个域名中的资源,由于同源策略的存在导致无法跨域访问,那么ajax就存在这种跨域问题。
关于同源问题,我们判断同源从三个要素着手:协议、域名、端口号。
如果协议一致,域名一致,端口号一致,三个要素都一致,才是同源,其它一律都是不同源
下面例子都是部署在两个服务器上,html代码是a服务器上的内容,servlet是b服务器上的内容。
这个比较简单,只需要在跨域访问资源的Servlet中添加代码:
response.setHeader("Access-Control-Allow-Origin", "http://localhost:8080"); // 允许某个 response.setHeader("Access-Control-Allow-Origin", "*"); // 允许所有
jsonp是一种类AJAX的请求机制,同样可以完成局部刷新的效果。但是jsonp只支持GET请求方式。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>jsonp跨域</title> </head> <body> <!-- 下面一行的代码效果是和下面22-28行的代码一样的 --> <!--<script type="text/javascript" src="http://localhost:8081/b/jsonp2?fun=sayHello"></script>--> <script type="text/javascript"> // data是一个json:{"username" : "lucy"} function sayHello(data){ document.getElementById("mydiv").innerHTML = data.username } window.onload = () => { document.getElementById("btn").onclick = () => { // 加载script元素 // 创建script元素对象 const htmlScriptElement = document.createElement("script"); // 设置script的type属性 htmlScriptElement.type = "text/javascript" // 设置script的src属性 htmlScriptElement.src = "http://localhost:8081/b/jsonp2?fun=sayHello" // 将script对象添加到body标签中(这一步就是加载script) document.getElementsByTagName("body")[0].appendChild(htmlScriptElement) } } </script> <button id="btn">jsonp解决跨域问题,达到ajax局部刷新的效果</button> <div id="mydiv"></div> </body> </html>
package com.bjpowernode.b.web.servlet; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/jsonp2") public class JSONPServlet2 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取函数名 String fun = request.getParameter("fun"); // 响应一段js代码 response.getWriter().print(fun + "({\"username\" : \"lucy\"})"); } }
jQuery中的jsonp其实就是我们上面代码的高度封装,底层原理完全相同。
核心代码:
$.ajax({ type : "GET", url : "跨域的url", dataType : "jsonp", // 指定数据类型 jsonp : "fun", // 指定参数名(不设置的时候,默认是:"callback") jsonpCallback : "sayHello" // 指定回调函数的名字 // (不设置的时候,jQuery会自动生成一个随机的回调函数, //并且这个回调函数还会自动调用success的回调函数。) })
后端代码同上。
使用Java程序发送get/post请求这里有两种方案:
第一种方案:使用JDK内置的API(java.net.URL…),这些API是可以发送HTTP请求的。
第二种方案:使用第三方的开源组件,比如:apache的httpclient组件。(httpclient组件是开源免费的,可以直接用)
这里我们说第二种方案。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>使用代理机制完成ajax跨域访问</title> </head> <body> <script type="text/javascript"> // ES6当中的有一个新语法:箭头函数。 window.onload = () => { document.getElementById("btn").onclick = () => { // 发送ajax请求 // 1.创建核心对象 const xmlHttpRequest = new XMLHttpRequest(); // const可以声明变量。(可以自己研究一下:var let const声明变量时有什么区别) // 2.注册回调函数 xmlHttpRequest.onreadystatechange = () => { if (xmlHttpRequest.readyState == 4) { // 这里也可以使用区间的方式,因为状态码是200~299都是正常响应结束。 if (xmlHttpRequest.status >= 200 && xmlHttpRequest.status < 300) { document.getElementById("mydiv").innerHTML = xmlHttpRequest.responseText } } } // 3.开启通道 xmlHttpRequest.open("GET", "/a/proxy", true) // 4.发送请求 xmlHttpRequest.send() } } </script> <button id="btn">使用代理机制解决ajax跨域访问</button> <div id="mydiv"></div> </body> </html>
这一部分的代码基本上都是模板套用,改改具体参数就好了。
package com.bjpowernode.javaweb.servlet; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @WebServlet("/proxy") public class ProxyServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 通过httpclient组件,发送HTTP GET请求,访问 TargetServlet HttpGet httpGet = new HttpGet("http://localhost:8081/b/target"); httpGet.setHeader("Content-Type", "application/x-www-form-urlencoded"); CloseableHttpClient httpClient = HttpClients.createDefault(); HttpResponse resp = httpClient.execute(httpGet); HttpEntity entity = resp.getEntity(); BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8")); String line = null; StringBuffer responseSB = new StringBuffer(); while ((line = reader.readLine()) != null) { responseSB.append(line); } reader.close(); httpClient.close(); // b站点响应回来的数据 response.getWriter().print(responseSB); } }
package com.bjpowernode.b.web.servlet; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/target") public class TargetServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 响应一个json字符串。 response.getWriter().print("{\"username\":\"jackson\"}"); } }
nginx反向代理中也是使用了这种代理机制来完成AJAX的跨域,实现起来非常简单,只要修改一个nginx的配置即可。
感谢各位的阅读,以上就是“AJAX跨域问题怎么解决”的内容了,经过本文的学习后,相信大家对AJAX跨域问题怎么解决这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。