国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術(shù)文章
文章詳情頁

AJAX跨域問題解決方案詳解

瀏覽:157日期:2022-06-12 09:04:53
目錄
  • 1.前言
  • 2.解決方案
    • 2.1 設(shè)置響應(yīng)頭
    • 2.2 jsonp
      • 2.2.1 前端代碼
      • 2.2.2 后端代碼
    • 2.3 使用jQuery封裝的jsonp
      • 2.4 代理機(jī)制(httpclient)
        • 2.4.1 前端代碼
        • 2.4.2 代理Servlet代碼
        • 2.4.3 目標(biāo)Servlet代碼
        • 2.4.4 圖示
      • 2.5 nginx反向代理

      1.前言

      跨域簡單的說,就是從一個(gè)域名的網(wǎng)頁去訪問另一個(gè)域名網(wǎng)頁的資源。

      通過超鏈接或者form表單提交或者window.location.href的方式進(jìn)行跨域是不存在問題的。但在一個(gè)域名的網(wǎng)頁中的一段js代碼發(fā)送ajax請求去訪問另一個(gè)域名中的資源,由于同源策略的存在導(dǎo)致無法跨域訪問,那么ajax就存在這種跨域問題。

      關(guān)于同源問題,我們判斷同源從三個(gè)要素著手:協(xié)議、域名、端口號。

      如果協(xié)議一致,域名一致,端口號一致,三個(gè)要素都一致,才是同源,其它一律都是不同源

      接下來我們來談?wù)刟jax中存在的跨域問題如何解決。

      2.解決方案

      下面例子都是部署在兩個(gè)服務(wù)器上,html代碼是a服務(wù)器上的內(nèi)容,servlet是b服務(wù)器上的內(nèi)容。

      2.1 設(shè)置響應(yīng)頭

      這個(gè)比較簡單,只需要在跨域訪問資源的Servlet中添加代碼:

      response.setHeader("Access-Control-Allow-Origin", "http://localhost:8080"); // 允許某個(gè)response.setHeader("Access-Control-Allow-Origin", "*"); // 允許所有

      2.2 jsonp

      jsonp是一種類AJAX的請求機(jī)制,同樣可以完成局部刷新的效果。但是jsonp只支持GET請求方式。

      2.2.1 前端代碼

      <!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是一個(gè)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");      // 設(shè)置script的type屬性      htmlScriptElement.type = "text/javascript"      // 設(shè)置script的src屬性      htmlScriptElement.src = "http://localhost:8081/b/jsonp2?fun=sayHello"      // 將script對象添加到body標(biāo)簽中(這一步就是加載script)      document.getElementsByTagName("body")[0].appendChild(htmlScriptElement)    }  }</script><button id="btn">jsonp解決跨域問題,達(dá)到ajax局部刷新的效果</button><div id="mydiv"></div></body></html>

      2.2.2 后端代碼

      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");// 響應(yīng)一段js代碼response.getWriter().print(fun + "({\"username\" : \"lucy\"})");    }}

      2.3 使用jQuery封裝的jsonp

      jQuery中的jsonp其實(shí)就是我們上面代碼的高度封裝,底層原理完全相同。

      核心代碼:

      $.ajax({    type : "GET",    url : "跨域的url",    dataType : "jsonp", // 指定數(shù)據(jù)類型    jsonp : "fun", // 指定參數(shù)名(不設(shè)置的時(shí)候,默認(rèn)是:"callback")    jsonpCallback : "sayHello" // 指定回調(diào)函數(shù)的名字							   // (不設(shè)置的時(shí)候,jQuery會(huì)自動(dòng)生成一個(gè)隨機(jī)的回調(diào)函數(shù),    						   //并且這個(gè)回調(diào)函數(shù)還會(huì)自動(dòng)調(diào)用success的回調(diào)函數(shù)。)})

      后端代碼同上。

      2.4 代理機(jī)制(httpclient)

      使用Java程序發(fā)送get/post請求這里有兩種方案:

      • 第一種方案:使用JDK內(nèi)置的API(java.net.URL…),這些API是可以發(fā)送HTTP請求的。
      • 第二種方案:使用第三方的開源組件,比如:apache的httpclient組件。(httpclient組件是開源免費(fèi)的,可以直接用)

      這里我們說第二種方案。

      2.4.1 前端代碼

      <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>使用代理機(jī)制完成ajax跨域訪問</title></head><body><script type="text/javascript">    // ES6當(dāng)中的有一個(gè)新語法:箭頭函數(shù)。    window.onload = () => {document.getElementById("btn").onclick = () => {    // 發(fā)送ajax請求    // 1.創(chuàng)建核心對象    const xmlHttpRequest = new XMLHttpRequest(); // const可以聲明變量。(可以自己研究一下:var let const聲明變量時(shí)有什么區(qū)別)    // 2.注冊回調(diào)函數(shù)    xmlHttpRequest.onreadystatechange = () => {if (xmlHttpRequest.readyState == 4) {    // 這里也可以使用區(qū)間的方式,因?yàn)闋顟B(tài)碼是200~299都是正常響應(yīng)結(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">使用代理機(jī)制解決ajax跨域訪問</button><div id="mydiv"></div></body></html>

      2.4.2 代理Servlet代碼

      這一部分的代碼基本上都是模板套用,改改具體參數(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請求,訪問 TargetServletHttpGet 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站點(diǎn)響應(yīng)回來的數(shù)據(jù)response.getWriter().print(responseSB);    }}

      2.4.3 目標(biāo)Servlet代碼

      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 {// 響應(yīng)一個(gè)json字符串。response.getWriter().print("{\"username\":\"jackson\"}");    }}

      2.4.4 圖示

      2.5 nginx反向代理

      nginx反向代理中也是使用了這種代理機(jī)制來完成AJAX的跨域,實(shí)現(xiàn)起來非常簡單,只要修改一個(gè)nginx的配置即可。這個(gè)再說。

      到此這篇關(guān)于AJAX跨域問題解決方案詳解的文章就介紹到這了,更多相關(guān)AJAX跨域內(nèi)容請搜索以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持!

      標(biāo)簽: Ajax
      相關(guān)文章:
      主站蜘蛛池模板: 美女扒开腿被男人猛视频 | 国产三级三级三级 | 久久亚洲精品一区成人 | 欧美亚洲另类视频 | 日韩一区二区三区在线视频 | 手机看片日韩国产一区二区 | 国产成人久久一区二区三区 | 欧美一级在线毛片免费观看 | 亚洲欧美一区二区三区在线 | 亚洲综合a| 九一国产精品视频 | 国内精品久久久久久久aa护士 | 久久久久久国产精品免费免 | 香蕉视频黄色在线观看 | 国产精品亚洲欧美日韩久久 | 国产精品国产三级国产普通 | 曰本人做爰大片免费观看一 | 黄色毛片在线 | 国产成人免费手机在线观看视频 | 99免费在线 | 久久九九有精品国产56 | 国产自一区 | 国产一级爱做片免费观看 | 国产v日韩v欧美v精品专区 | 1717she国产精品免费视频 | 一级片在线观看视频 | 一级做a爰片性色毛片视频图片 | 国产区网址 | 韩国一级黄色大片 | 1a级毛片免费观看 | 亚洲加勒比在线 | 国产欧美日韩精品高清二区综合区 | 日本一区二区三区高清福利视频 | 欧美日韩精彩视频 | 成人久久久 | 在线亚洲精品 | 狠狠色丁香婷婷久久综合考虑 | 日本国产在线视频 | 韩国福利一区 | 亚洲成在人线中文字幕 | 久久福利青草精品免费 |