關於跨域問題的幾種解決方案


 

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");
                    
                }

成功解決:

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM