1.什么是跨域?
跨域:指的是瀏覽器不能執行其他網站的腳本。它是由瀏覽器的同源策略造成的,是瀏覽器對javascript施加的安全限制。
例如:a頁面想獲取b頁面資源,如果a、b頁面的協議、域名、端口、子域名不同,所進行的訪問行動都是跨域的,而瀏覽器為了安全問題一般都限制了跨域訪問,也就是不允許跨域請求資源。注意:跨域限制訪問,其實是瀏覽器的限制。理解這一點很重要!!!
同源策略:是指協議,域名,端口都要相同,其中有一個不同都會產生跨域;

跨域原因產生:在當前域名請求網站中,默認不允許通過ajax請求發送其他域名。
解決方案:
一.跨域問題:能夠正常請求,但是沒有辦法獲取到響應結果
b工程中直接在ajax訪問a工程servlet
1 $(function(){ 2 $("#button").click(function () { 3 //獲取到文本框的值 4 var username=$("#username").val(); 5 //發送Ajax請求www.a.com的A工程 6 $.ajax({ 7 url:"http://www.a.com:8080/projectA/AServlet?username="+username, 8 type:"GET", 9 success:function (result) { 10 alert(result); 11 }, 12 error:function () { 13 alert('系統錯誤~') 14 } 15 }); 16 }); 17 });
A工程中能正確接收值
但是success回調函數會報錯提示
No 'Access-Control-Allow-Origin' header
解決方案一:設置請求頭,在請求的資源中設置Access-Control-Allow-Origin請求頭
//設置請求頭
1 response.setHeader("Access-Control-Allow-Origin", "*");
正常回調
解決方案二:JSONP解決跨域問題
普通的跨域訪問問題,瀏覽器會進行攔截,凡是src屬性的都不會攔截
JSONP實現原理:動態加載<script>標簽,利用src屬性進行服務器資源的訪問,但是只支持Get請求
1.在我們的Ajax請求當中,需要以JSONP方式請求(通過jquery手段,動態生成script)
jsonp:"代表的是前台傳給后台,后台再傳遞給你 jsonpCallBack"
2.在AJAX請求當中需要將返回的數據格式指定為jsonp
dataType:"JSONP"
3.JSONP需要以Get請求發送
?username=zhangsan
4.后台需要做的事情:
1.正常接收數據
2.返回數據
前台傳遞過來的jsonp需要原路返回
String jsonp=request.getParameter("jsonpCallBack");
需要將返回的數據轉換為JSON success
response.getWirter.write(jsonp+"("+返回的數據+")");
修改Ajax請求:
$(function(){ $("#button").click(function () { //獲取到文本框的值 var username=$("#username").val(); //發送Ajax請求www.a.com的A工程 $.ajax({ url:"http://www.a.com:8080/projectA/AServlet?username="+username, type:"GET", jsonp:"jsonpCallBack", //回調函數 dataType:"JSONP", success:function (result) { alert(result); }, error:function () { alert('系統錯誤~') } }); }); });
更改后台請求,需要將JSONP原路返回
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.接受數據 String username=request.getParameter("username"); System.out.println("接收的數據:"+username); //接受Ajax傳遞的數據 String jsonpCallBack = request.getParameter("jsonpCallBack"); System.out.println("jsonpCallBack:"+jsonpCallBack); String success = JSON.toJSONString("success"); response.getWriter().write(jsonpCallBack+"("+success+")"); }
成功解決:
解決方案三:使用HTTPClient解決:就是不通過瀏覽器發送請求
B工程的頁面發送的Ajax沒有辦法請求到A工程,因為瀏覽器會攔截,走后台,后台通過HTTPClient請求請求到A工程,獲取到響應結果
1.B工程的bindex.jsp頁面請求到B工程的Servlet
$(function(){ $("#button").click(function () { //獲取到文本框的值 var username=$("#username").val(); //發送Ajax請求www.a.com的A工程 $.ajax({ url:"BServlet?username="+username, type:"GET", success:function (result) { alert(result); }, error:function () { alert('系統錯誤~') } }); }); });
2.B工程的BServlet去模擬HTTP請求到A工程
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //內部通過HTTPClient進行轉發 //構建一個連接 CloseableHttpClient client = HttpClients.createDefault(); //構建請求 HttpGet get=new HttpGet("http://www.a.com:8080/projectA/AServlet?username="+request.getParameter("username")); //發送請求 CloseableHttpResponse httpResponse = client.execute(get); //獲取返回結果 String result = EntityUtils.toString(httpResponse.getEntity()); //將A工程響應結果給頁面 response.getWriter().write(result); }
3.A工程處理請求
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.接受數據 String username=request.getParameter("username"); System.out.println("接受的數據:"+username); //2.響應結果 response.getWriter().write("success"); }
成功解決: