您好,登錄后才能下訂單哦!
這篇文章主要講解了“AJAX跨域問題怎么解決”,文中的講解內(nèi)容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“AJAX跨域問題怎么解決”吧!
跨域簡單的說,就是從一個域名的網(wǎng)頁去訪問另一個域名網(wǎng)頁的資源。
通過超鏈接或者form表單提交或者window.location.href的方式進行跨域是不存在問題的。但在一個域名的網(wǎng)頁中的一段js代碼發(fā)送ajax請求去訪問另一個域名中的資源,由于同源策略的存在導致無法跨域訪問,那么ajax就存在這種跨域問題。
關(guān)于同源問題,我們判斷同源從三個要素著手:協(xié)議、域名、端口號。
如果協(xié)議一致,域名一致,端口號一致,三個要素都一致,才是同源,其它一律都是不同源
下面例子都是部署在兩個服務器上,html代碼是a服務器上的內(nèi)容,servlet是b服務器上的內(nèi)容。
這個比較簡單,只需要在跨域訪問資源的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元素 // 創(chuàng)建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 { // 獲取函數(shù)名 String fun = request.getParameter("fun"); // 響應一段js代碼 response.getWriter().print(fun + "({\"username\" : \"lucy\"})"); } }
jQuery中的jsonp其實就是我們上面代碼的高度封裝,底層原理完全相同。
核心代碼:
$.ajax({ type : "GET", url : "跨域的url", dataType : "jsonp", // 指定數(shù)據(jù)類型 jsonp : "fun", // 指定參數(shù)名(不設置的時候,默認是:"callback") jsonpCallback : "sayHello" // 指定回調(diào)函數(shù)的名字 // (不設置的時候,jQuery會自動生成一個隨機的回調(diào)函數(shù), //并且這個回調(diào)函數(shù)還會自動調(diào)用success的回調(diào)函數(shù)。) })
后端代碼同上。
使用Java程序發(fā)送get/post請求這里有兩種方案:
第一種方案:使用JDK內(nèi)置的API(java.net.URL…),這些API是可以發(fā)送HTTP請求的。
第二種方案:使用第三方的開源組件,比如:apache的httpclient組件。(httpclient組件是開源免費的,可以直接用)
這里我們說第二種方案。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>使用代理機制完成ajax跨域訪問</title> </head> <body> <script type="text/javascript"> // ES6當中的有一個新語法:箭頭函數(shù)。 window.onload = () => { document.getElementById("btn").onclick = () => { // 發(fā)送ajax請求 // 1.創(chuàng)建核心對象 const xmlHttpRequest = new XMLHttpRequest(); // const可以聲明變量。(可以自己研究一下:var let const聲明變量時有什么區(qū)別) // 2.注冊回調(diào)函數(shù) xmlHttpRequest.onreadystatechange = () => { if (xmlHttpRequest.readyState == 4) { // 這里也可以使用區(qū)間的方式,因為狀態(tài)碼是200~299都是正常響應結(jié)束。 if (xmlHttpRequest.status >= 200 && xmlHttpRequest.status < 300) { document.getElementById("mydiv").innerHTML = xmlHttpRequest.responseText } } } // 3.開啟通道 xmlHttpRequest.open("GET", "/a/proxy", true) // 4.發(fā)送請求 xmlHttpRequest.send() } } </script> <button id="btn">使用代理機制解決ajax跨域訪問</button> <div id="mydiv"></div> </body> </html>
這一部分的代碼基本上都是模板套用,改改具體參數(shù)就好了。
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組件,發(fā)送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站點響應回來的數(shù)據(jù) 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的跨域,實現(xiàn)起來非常簡單,只要修改一個nginx的配置即可。
感謝各位的閱讀,以上就是“AJAX跨域問題怎么解決”的內(nèi)容了,經(jīng)過本文的學習后,相信大家對AJAX跨域問題怎么解決這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。