<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
跨域簡單的說,就是從一個域名的網頁去存取另一個域名網頁的資源。
通過超連結或者form表單提交或者window.location.href的方式進行跨域是不存在問題的。但在一個域名的網頁中的一段js程式碼傳送ajax請求去存取另一個域名中的資源,由於同源策略的存在導致無法跨域存取,那麼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 lang="en"> <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請求這裡有兩種方案:
這裡我們說第二種方案。
<!DOCTYPE html> <html lang="en"> <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跨域內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45