日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

ajax跨域问题以及解决方案_js跨域请求的三种方法

發(fā)布時(shí)間:2023/12/19 综合教程 34 生活家
生活随笔 收集整理的這篇文章主要介紹了 ajax跨域问题以及解决方案_js跨域请求的三种方法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

出于瀏覽器的同源策略限制。同源策略(Sameoriginpolicy)是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能可能都會(huì)受到影響??梢哉fWeb是構(gòu)建在同源策略基礎(chǔ)之上的,瀏覽器只是針對(duì)同源策略的一種實(shí)現(xiàn)。同源策略會(huì)阻止一個(gè)域的javascript腳本和另外一個(gè)域的內(nèi)容進(jìn)行交互。所謂同源(即指在同一個(gè)域)就是兩個(gè)頁(yè)面具有相同的協(xié)議(protocol),主機(jī)(host)和端口號(hào)(port)

AJAX跨域請(qǐng)求

下面簡(jiǎn)單模擬一個(gè)場(chǎng)景—–>>
前端有一個(gè)頁(yè)面

鼠標(biāo)離開用戶名輸入框時(shí),檢查是否符合要求,如果為空,則給提示,如果不為空,則異步查詢數(shù)據(jù)庫(kù),后返回結(jié)果;

本次請(qǐng)求的頁(yè)面是8082端口的,而響應(yīng)的ajax路徑卻是8080端口的

前端代碼—>

<!DOCTYPE html>
<html>
<head>
<title>$Title%sSourceCod</title>
<meta charset="UTF-8"/>
<script src="js/jquery-3.5.1.min.js"></script>
<script> function checkUname(){ 
 // 獲取輸入框中的內(nèi)容 if(null == $("#unameI").val() || '' == $("#unameI").val()){ 
 $("#unameInfo").text("用戶名不能為空"); return; } $("#unameInfo").text(""); // 通過jQuery.ajax() 發(fā)送異步請(qǐng)求 $.ajax( { 
 type:"GET",// 請(qǐng)求的方式 GET POST url:"http://localhost:8080/loadPicture_war_exploded/checkName.do?", // 請(qǐng)求的后臺(tái)服務(wù)的路徑 data:"uname="+$("#unameI").val(),// 提交的參數(shù) success:function(info){ 
 // 響應(yīng)成功執(zhí)行的函數(shù) $("#unameInfo").text(info) } } ) } </script>
</head>
<body>
<form action="myServlet1.do" >
用戶名:<input id="unameI" type="text" name="uname" onblur="checkUname()">
<span id="unameInfo"></span><br/>
密碼:<input type="password" name="pwd"><br/>
<input type="submit" value="提交按鈕">
</form>
</body>
</html>

后端代碼—>

package com.gavin.controller;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/checkName.do")
public class testAjax extends HttpServlet { 

@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 

String uname = req.getParameter("uname");
String callBack = req.getParameter("aaa");
System.out.println(uname);
String info = "";
if ("gavin".equals(uname)) { 

info = "用戶名已經(jīng)占用";
} else { 

info = "用戶名可用";
}
// 向?yàn)g覽器響應(yīng)數(shù)據(jù)
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/javaScript;charset=UTF-8");
resp.getWriter().print(callBack + "('" + info + "')");
}
}

訪問的時(shí)候?yàn)g覽器提示—>

原因—>

對(duì) CORS 請(qǐng)求的響應(yīng)缺少必需的Access-Control-Allow-Origin頭,其用于確定在當(dāng)前源內(nèi)操作的資源是否可以訪問。
如果服務(wù)器在您的控制之下,請(qǐng)將請(qǐng)求站點(diǎn)的源添加到允許訪問的域集,方法是將其添加到Access-Control-Allow-Origin頭的值。


為什么會(huì)有跨域呢?
因?yàn)閷?shí)際應(yīng)用中分布式與集群會(huì)涉及到跨域,前端服務(wù)器與后端服務(wù)器分離,前端服務(wù)異步請(qǐng)求后端服務(wù)器就涉及到了跨域;

由于瀏覽器的同源策略,所以跨服務(wù)器訪問會(huì)有一些小麻煩,先一步一步探索去解決;

這個(gè)時(shí)候js文件能不能加載生效呢? 答案是生效了;

Web頁(yè)面上調(diào)用js文件時(shí)可以跨域,也就是后擁有”src”這個(gè)屬性的標(biāo)簽都卻擁有跨域的能力

那么我們轉(zhuǎn)變思路,如果將異步請(qǐng)求轉(zhuǎn)到j(luò)s文件身上
比如我們可以這么做

后端可以接收到前端數(shù)據(jù);
但是這樣寫看起來怪怪的,而且實(shí)際上這樣異步請(qǐng)求中的url依然會(huì)被瀏覽器攔截

如果去掉這個(gè)url,會(huì)發(fā)生不可描述的事情,像這樣—-整個(gè)span被頁(yè)面代碼填滿,

那怎么處理呢?

此時(shí)異步請(qǐng)求添加一個(gè)屬性—dataType:“jsonp”
這樣就可以正常一點(diǎn)實(shí)現(xiàn)跨域的異步請(qǐng)求了—>

        function checkUname(){
// 獲取輸入框中的內(nèi)容
if(null == $("#unameI").val() || '' == $("#unameI").val()){
$("#unameInfo").text("用戶名不能為空");
return;
}
$("#unameInfo").text("");
// 通過jQuery.ajax() 發(fā)送異步請(qǐng)求
$.ajax(
{
type:"GET",// 請(qǐng)求的方式 GET  POST
url:"http://localhost:8080/loadPicture_war_exploded/checkName.do?", // 請(qǐng)求的后臺(tái)服務(wù)的路徑
data:"uname="+$("#unameI").val(),// 提交的參數(shù)
dataType:"jsonp",
success:function(info){ // 響應(yīng)成功執(zhí)行的函數(shù)
$("#unameInfo").text(info)
}
}
)
}

原因—->>

雖然跨域請(qǐng)求實(shí)現(xiàn)了,但是前端接收不到后端返回的數(shù)據(jù),即異步 請(qǐng)求中的success方法失效了,
為什么失效?因?yàn)槿绻峭ㄟ^script來完成異步請(qǐng)求,那么返回的內(nèi)容應(yīng)該是一個(gè)js代碼,

既然是這樣,我們要想在span中添加返回類的信息,那么我們不妨在前端寫一個(gè)方法,用于專門像span中添加信息—然后后端返回的信息來直接調(diào)這個(gè)方法就好了;

			function showInfo(info){
$("#unameInfo").val(info);
}

后端返回的數(shù)據(jù)


運(yùn)行原理——>>>>

解決一個(gè)小痛點(diǎn),前端方法名隨時(shí)可能變化,為了降低耦合度,一般會(huì)這么做,前端發(fā)送的數(shù)據(jù)中攜帶該方法名;


前面不是說success廢了嗎?我就想用這個(gè)方法,不想在額外定義一個(gè)別的showInfo方法,那么這個(gè)該怎么做呢?
在異步請(qǐng)求上添加一個(gè)參數(shù):
jsonp:“任意的名稱A”


GetJson實(shí)現(xiàn)跨域請(qǐng)求

	        function checkUname(){
// 獲取輸入框中的內(nèi)容
if(null == $("#unameI").val() || '' == $("#unameI").val()){
$("#unameInfo").text("用戶名不能為空");
return;
}
$("#unameInfo").text("");
$.getJSON(
"http://localhost:8080/loadPicture_war_exploded/checkName.do?jsoncallback=?",
{uname:$("#unameI").val()},
function(info){
$("#unameInfo").text(info)
}
)
}

通過后臺(tái)代碼也可以實(shí)現(xiàn)跨域,一般在過濾器中添加如下代碼,那么前端在請(qǐng)求時(shí)就不用考慮跨域問題了

/*請(qǐng)求地址白名單 *代表所有 /
resp.setHeader(“Access-Control-Allow-Origin”, “
“);
/*請(qǐng)求方式白名單 */
resp.setHeader(“Access-Control-Allow-Methods”, “POST, GET, OPTIONS, DELETE”);
resp.setHeader(“Access-Control-Max-Age”, “3600”);
resp.setHeader(“Access-Control-Allow-Headers”, “x-requested-with”);

在結(jié)合springmvc之后,可以通過一個(gè)注解來完成跨域

CrossOrigin注解實(shí)現(xiàn)跨域

package com.gavin.controller;
import com.gavin.pojo.AlertMsg;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
public class AjaxTEST  { 

@CrossOrigin(value ="http://127.0.0.1:8020" )
@RequestMapping("/checkName3.do")
@ResponseBody
public AlertMsg checkUserName(@RequestBody AlertMsg alertMsg)  { 

System.out.println(alertMsg);
if ("gavin".equals(alertMsg.getUname())) { 

alertMsg.setMsg("用戶名已經(jīng)占用");
} else { 

alertMsg.setMsg( "用戶名可用");
}
// 向?yàn)g覽器響應(yīng)數(shù)據(jù)----返回一個(gè)json格式的數(shù)據(jù)
System.out.println(alertMsg);
return alertMsg;
}
}
			function checkUname3() {
// 獲取輸入框中的內(nèi)容
if(null == $("#unameI3").val() || '' == $("#unameI3").val()) {
$("#unameInfo3").text("用戶名不能為空");
return;
}
$("#unameInfo3").text("");
var str = $("#unameI3").val();
$.ajax({
type: "post",
url: "http://localhost:8080/loadPicture_war_exploded/checkName3.do?",
//					data:{uname:$("#unameI3").val(),msg:""},
//data:{"uname":$("#unameI3").val(),"msg":""},
data: JSON.stringify({
uname: $("#unameI3").val()
}),
dataType: "json",
contentType: "application/json;charset=UTF-8",
success: function(data) {
$("#unameInfo3").text(data.msg);
}
});
}


關(guān)于json對(duì)象的一些感悟與理解;
前端傳過來的數(shù)據(jù)—-可能是字符串,也可能是json對(duì)象,但是在處理的時(shí)候還是以字符串進(jìn)行處理的,
JSON.stringify()方法是將一個(gè)JavaScript對(duì)象轉(zhuǎn)換成符合JSON格式的字符串,然后后端通過解析字符串在轉(zhuǎn)化為一個(gè)json對(duì)象;
所以
ajax跨域的解決方案有種了,
第一種是 jsonp的形式,
另一種是getjson()
最后一種是注解CrossOrigin

總結(jié)

以上是生活随笔為你收集整理的ajax跨域问题以及解决方案_js跨域请求的三种方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。