頭疼的跨域問題到底應該怎麼處理?(彙總)

 

本文主要解決linux服務器下的配置;windows基本上修改http頭就能好.其他環境可以作爲參考,肯定有益

跨域的表現

我貼一段文字的提示,這樣搜索引擎就能抓取到,然後就會吸引你進來了.如果你就是這樣被吸引的 ,請點贊,然後繼續往下看:

No 'Access-Control-Allow-Origin' header is present on the requested resource

 XMLHttpRequest cannot load * The 'Access-Control-Allow-Origin' header has a value * that is not equal to the supplied origin. Origin * is therefore notallowed access.

Access to XMLHttpRequest at '*' from origin '*' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

常見的解決方案

遇到跨域問題

1 你可能會這樣(修改後端代碼)(這樣後端程序員要被逼成啥樣才能寫出來這樣的!!)

//.net
   //解決跨域
   app.UseHttpsRedirection().UseCors(builder => builder.AllowAnyMethod());
   app.UseHttpsRedirection().UseCors(builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
//java
    response.setHeader("Access-Control-Allow-Origin", "http://www.domain1.com"); 
    response.setHeader("Access-Control-Allow-Credentials", "true"); 
    response.setHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With");
//Nodejs後臺 
    res.writeHead(200, {
            'Access-Control-Allow-Credentials': 'true',    
            'Access-Control-Allow-Origin': 'http://www.domain.com',  
    });
    res.write(JSON.stringify(postData));
    res.end();
//php
    header('Access-Control-Allow-Origin:*');//允許所有來源訪問
    header('Access-Control-Allow-Method:POST,GET');//允許訪問的方式
//jquery
    jQuery.support.cors = true;
    或
    processData: false
//vue-cli   
    app.all('*', function (req, res, next) {
      res.header("Access-Control-Allow-Origin", "*");
      res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length,     Authorization, Accept, X-Requested-With , yourHeaderFeild');
      res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
      res.header("X-Powered-By", ' 3.2.1')
      res.header("Content-Type", "application/json;charset=utf-8");
      next();
    });
//python
    #設置可跨域範圍
    CORS_ALLOW_CREDENTIALS = True
    CORS_ORIGIN_ALLOW_ALL = True
    #定義跨域中間件
    'corsheaders.middleware.CorsMiddleware',

2 也可能會這樣(修改http響應標頭)(代表微軟感謝你還在支持C#或者asp)

3 還可能是這樣(iframe)(前端寶寶辛苦了)

<iframe id="iframe" src="http://aaa.domain.com/aaa.html"></iframe>
<script>
    document.domain = 'domain.com';
    var user = 'admin';
</script>

4 還有這樣的吧(設置圖片的和xhr的)(這樣也只能解決圖片,其他數據請求解決不了找後端吧)


var gl = ...;
var image = new Image();
image.onload = ...;
image.crossOrigin = "anonymous";
image.src = "http://other-domain.com/image.jpg";

5 還有配置前端框架的(vue等)(這個框架一直想學,聽說很香)

a.) axios設置:

axios.defaults.withCredentials = true

b.) vue-resource設置:

Vue.http.options.credentials = true

6 還有設置後端服務的(Nginx)(運維同學,熬夜傷不起)

location / {  
    add_header Access-Control-Allow-Origin *;
} 

7 還有socketio的(socket)(這種用的都是資深的程序員了)

<div>user input:<input type="text"></div>
<script src="https://cdn.bootcss.com/socket.io/2.2.0/socket.io.js"></script>
<script>
var socket = io('http://www.domain2.com:8080');

// 連接成功處理
socket.on('connect', function() {
    // 監聽服務端消息
    socket.on('message', function(msg) {
        console.log('data from server: ---> ' + msg); 
    });

    // 監聽服務端關閉
    socket.on('disconnect', function() { 
        console.log('Server socket has closed.'); 
    });
});

document.getElementsByTagName('input')[0].onblur = function() {
    socket.send(this.value);
};
</script>

8 增加請求(mate)(IE可能好了.但是你別高興的早,你敢試試別的嗎?哭)

<meta http-equiv="Access-Control-Allow-Origin" content="*" />

其他 還在蒐集整理中.......(歡迎留言)

那麼問題來了

嘗試了很多,到底怎麼解決呢?

解決之前,首頁我們先了解一下爲什麼會跨域.我找別人的代碼粘貼過來吧

那些情況會跨域

既然你都看到這裏了. 下面黑框裏面的你肯定能找到和你雷同的.(如有雷同,不勝榮幸)

URL                                      說明                    是否允許通信
http://www.domain.com/a.js
http://www.domain.com/b.js         同一域名,不同文件或路徑           允許
http://www.domain.com/lab/c.js

http://www.domain.com:8000/a.js
http://www.domain.com/b.js         同一域名,不同端口                不允許
 
http://www.domain.com/a.js
https://www.domain.com/b.js        同一域名,不同協議                不允許
 
http://www.domain.com/a.js
http://192.168.4.12/b.js           域名和域名對應相同ip              不允許
 
http://www.domain.com/a.js
http://x.domain.com/b.js           主域相同,子域不同                不允許
http://domain.com/c.js
 
http://www.domain1.com/a.js
http://www.domain2.com/b.js        不同域名                         不允許

下面不亂扯了, 加班回家了

跨域 http返回狀態都不對. 這個一定要打開F12查一下請求的返回值

常見狀態

一般是405.請求的Request Method:OPTIONS . 

劃重點了~~~~~~~

跨域資源共享(CORS)標準:瀏覽器必須首先使用 OPTIONS 方法發起一個預檢請求,返回204後,才發起實際的 HTTP 請求

錯誤的:

正確的:

跨域的話Post那條是看不到的

所有要攻克的話要讓服務器對OPTIONS 返回204

所以

if ($request_method = 'OPTIONS') {
        return 204;
}

具體代碼如下


    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

    if ($request_method = 'OPTIONS') {
        return 204;
    }

這段代碼加到哪裏.如果不清楚.你可以留言. 因爲你的服務器配置不一樣, 也不好以偏概全.

當然,我開頭寫的很多情況, 並不是解決不了問題. 只要知道原理,再去實現才行.

官方資料:

HTTP訪問控制(CORS) https://developer.mozilla.org/en-US/docs/Glossary/CORS

XMLHttpRequest原理 : https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest

跨域資源共享 CORS 詳解 : http://www.ruanyifeng.com/blog/2016/04/cors.html

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章