前端請求接口地址跨域


一.什么是跨域?

出於瀏覽器的同源策略限制。同源策略(Sameoriginpolicy)是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能可能都會受到影響。可以說Web是構建在同源策略基礎之上的,瀏覽器只是針對同源策略的一種實現。同源策略會阻止一個域的javascript腳本和另外一個域的內容進行交互。所謂同源(即指在同一個域)就是兩個頁面具有相同的協議(protocol),主機(host)和端口號(port)。

所以說造成跨域的原因是三個:

1.協議的不同。例如:http和https。

2.主機,也就是域名。比如:www.baidu.com和www.taobao.con。

3.端口號。比如8080和8888。

當前頁面url 被請求頁面url 是否跨域 原因
http://www.test.com/ http://www.test.com/index.html 同源(協議、域名、端口號相同)
http://www.test.com/ https://www.test.com/index.html 跨域 協議不同(http/https)
http://www.test.com/ http://www.baidu.com/ 跨域 主域名不同(test/baidu)
http://www.test.com/ http://blog.test.com/ 跨域 子域名不同(www/blog)
http://www.test.com:8080/ http://www.test.com:7001/ 跨域 端口號不同(8080/7001)

二.跨域解決方法

JSONP:  Jsonp(JSON with Padding) 是 json 的一種"使用模式",可以讓網頁從別的域名(網站)那獲取資料,即跨域讀取數據。

最大特點就是簡單適用,兼容性好(兼容低版本IE),缺點是只支持get請求,不支持post請求。

1.原生實現:

<script src="http://test.com/data.php?callback=dosomething"></script>
// 向服務器test.com發出請求,該請求的查詢字符串有一個callback參數,用來指定回調函數的名字
 
// 處理服務器返回回調函數的數據
<script type="text/javascript">
    function dosomething(res){
        // 處理獲得的數據
        console.log(res.data)
    }
</script>
 

2. jQuery ajax:

$.ajax({
    url: 'http://www.test.com:8080/login',
    type: 'get',
    dataType: 'jsonp',  // 請求方式為jsonp
    jsonpCallback: "handleCallback",    // 自定義回調函數名
    data: {}
});

3. Vue.js

this.$http.jsonp('http://www.domain2.com:8080/login', {
    params: {},
    jsonp: 'handleCallback'
}).then((res) => {
    console.log(res); 
})

后台設置跨域解決方案:

① Java后台:

/*
 * 導入包:import javax.servlet.http.HttpServletResponse;
 * 接口參數中定義:HttpServletResponse response
 */
 
// 允許跨域訪問的域名:若有端口需寫全(協議+域名+端口),若沒有端口末尾不用加'/'
response.setHeader("Access-Control-Allow-Origin", "http://www.domain1.com"); 
 
// 允許前端帶認證cookie:啟用此項后,上面的域名不能為'*',必須指定具體的域名,否則瀏覽器會提示
response.setHeader("Access-Control-Allow-Credentials", "true"); 
 
// 提示OPTIONS預檢時,后端需要設置的兩個常用自定義頭
response.setHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With");

② Nodejs后台

var http = require('http');
var server = http.createServer();
var qs = require('querystring');
 
server.on('request', function(req, res) {
    var postData = '';
 
    // 數據塊接收中
    req.addListener('data', function(chunk) {
        postData += chunk;
    });
 
    // 數據接收完畢
    req.addListener('end', function() {
        postData = qs.parse(postData);
 
        // 跨域后台設置
        res.writeHead(200, {
            'Access-Control-Allow-Credentials': 'true',     // 后端允許發送Cookie
            'Access-Control-Allow-Origin': 'http://www.domain1.com',    // 允許訪問的域(協議+域名+端口)
            /* 
             * 此處設置的cookie還是domain2的而非domain1,因為后端也不能跨域寫cookie(nginx反向代理可以實現),
             * 但只要domain2中寫入一次cookie認證,后面的跨域接口都能從domain2中獲取cookie,從而實現所有的接口都能跨域訪問
             */
            'Set-Cookie': 'l=a123456;Path=/;Domain=www.domain2.com;HttpOnly'  // HttpOnly的作用是讓js無法讀取cookie
        });
 
        res.write(JSON.stringify(postData));
        res.end();
    });
});
 
server.listen('8080');
console.log('Server is running at port 8080...');

代理配置

針對於vue項目講解

如果你的項目使用的是vue-cli腳手架創建的項目,那么你需要在vue.config.js中添加

devServer的配置。

https://www.webpackjs.com/configuration/dev-server/#devserver。

具體的配置請參見鏈接。

module.exports = {
    devServer: {
        open: true,
        host: 'localhost',
        port: 8080,
        https: false,
        //以上的ip和端口是我們本機的;下面為需要跨域的
        proxy: {//配置跨域
            '/api': {
                target: 'http://localhost:5001/api/',//這里后台的地址模擬的;應該填寫你們真實的后台接口
                ws: true,
                changOrigin: true,//允許跨域
                pathRewrite: {
                    '^/api': ''//請求的時候使用這個api就可以
                }
            }
            
        }
    }
}

 


免責聲明!

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



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