當前位置:首頁 » 編程軟體 » 誇域腳本

誇域腳本

發布時間: 2023-02-01 01:40:47

❶ Nginx的反向代理跨域

什麼是跨域?

跨域是指a頁面想獲取b頁面資源,如果a、b頁面的協議、域名、埠、子域名不同,或是a頁面為ip地址, b頁面為域名地址,所進行的訪問行動都是跨域

瀏覽器為了安全問題一般都限制了跨域訪問,也就是不允許跨域請求資源

同ip(或domain),同埠,同協議視為同一個域,一個域內的腳本僅僅具有本域內的許可權,可以理解為本域腳本只能讀寫 本域內的資源,而無法訪問其它域的資源。這種安全限制稱為同源策略

現代瀏覽器在安全性和可用性之間選擇了一個平衡點。 在遵循同源策略的基礎上,選擇性地為同源策略「開放了後門」。例如img script style等標簽,都允許垮域引用資源,然而, 你也只能是引用這些資源而已,並不能讀取這些資源的內容

同源策略限制以下幾種行為:

1.Cookie、LocalStorage 和 IndexDB 無法讀取

2.DOM 和 Js對象無法獲得

3.AJAX 請求不能發送

http://www.domain.com/a.jshttp://www.domain.com/b.js 同一域名,不同文件或路徑 允許http://www.domain.com/lab/c.jshttp://www.domain.com:8000/a.jshttp://www.domain.com/b.js 同一域名,不同埠 不允許http://www.domain.com/a.jshttps://www.domain.com/b.js 同一域名,不同協議 不允許http://www.domain.com/a.jshttp://192.168.4.12/b.js 域名和域名對應相同ip 不允許http://www.domain.com/a.jshttp://x.domain.com/b.js 主域相同,子域不同 不允許http://domain.com/c.jshttp://www.domain1.com/a.jshttp://www.domain2.com/b.js 不同域名 不允許

1、 通過jsonp跨域

2、 document.domain + iframe跨域

3、 location.hash + iframe

4、 window.name + iframe跨域

5、 postMessage跨域

6、 跨域資源共享(CORS)

7、 nginx代理跨域

8、 nodejs中間件代理跨域

9、 WebSocket協議跨域

正向代理 :代理位於網站和客戶端中間, 客戶端無法訪問某網站,就將請求發送給代理伺服器,代理從網站取回來再發送給客戶端,網站並不知道為誰提供服務

反向代理 :客戶端訪問某網站的一個頁面, 但是網站並沒有,就偷偷從另外一台伺服器上取回來,然後作為自己的內容吐給用戶,用戶不知道真正提供服務的是誰

對於瀏覽器來說,訪問的就是同源伺服器上的一個url。而nginx通過 檢測url前綴,把http請求轉發到後面真實的物理伺服器。並通過rewrite命令把前綴再去掉。這樣真實的伺服器就可以正確 處理請求,並且並不知道這個請求是來自代理伺服器的。

簡單說,nginx伺服器欺騙了瀏覽器,讓它認為這是同源調用,從而解決了瀏覽器的跨域問題。又通過重寫url,欺騙了真實 的伺服器,讓它以為這個http請求是直接來自與用戶瀏覽器的。

Location/carrots-admin-ajax/{

    proxy_passhttp://dev.admin.carrots.ptteng.com/;

}

proxy_pass 把請求代理到其他主機

兩種寫法hhttp://dev.admin.carrots.ptteng.com/    和     http://dev.admin.carrots.ptteng.com

    如果訪問url = http://server/html/test.jsp ,則被nginx代理後

        情況1,將test/作為根路徑,請求test/路徑下的資源。

        情況2,則被nginx代理後,請求路徑會變為http://proxy_pass/test.jsp,直接訪問server的根資源。

是一個匹配規則,用於攔截請求,匹配任何以/proxy/html/開頭的地址,匹配符合以後,停止往下搜索正則。

對於瀏覽器來說,訪問的就是同源伺服器上的一個url。而nginx通過檢測url前綴,把http請求轉發到後面真實的物理伺服器。並通過rewrite命令把前綴再去掉。這樣真實的伺服器就可以正確處理請求,並且並不知道這個請求是來自代理伺服器的。

簡單說,nginx伺服器欺騙了瀏覽器,讓它認為這是同源調用,從而解決了瀏覽器的跨域問題。又通過重寫url,欺騙了真實的伺服器,讓它以為這個http請求是直接來自與用戶瀏覽器的。

1.執行server塊的rewrite指令(這里的塊指的是server關鍵字後{}包圍的區域,其它xx塊類似)

2.執行location匹配

3.執行選定的location中的rewrite指令

如果其中某步URI被重寫,則重新循環執行1-3,直到找到真實存在的文件

如果循環超過10次,則返回500 Internal Server Error錯誤

7.參考文獻

參考一: https://www.cnblogs.com/gabrielchen/p/5066120.html

參考二: http://blog.csdn.net/shendl/article/details/48443299

8.更多討論

提問:

Q :例如img script style等標簽,都允許垮域引用資源?

A :在瀏覽器中,並且載入的方式其實相當於一次普通的GET請求,唯一不同的是,為了安全起見,瀏覽器不允許這種方式下對載入到的資源的讀寫操作,而只能使用標簽本身應當具備的能力(比如腳本執行、樣式應用等等)。

Q :例如img script style等標簽,都允許垮域引用資源?

A :在瀏覽器中,並且載入的方式其實相當於一次普通的GET請求,唯一不同的是,為了安全起見,瀏覽器不允許這種方式下對載入到的資源的讀寫操作,而只能使用標簽本身應當具備的能力(比如腳本執行、樣式應用等等)。

Q:JSONP和nginx跨域有什麼不同

JSONP和nginx是完全不同的 是可以跨域的,而且在跨域腳本中可以直接回調當前腳本的函數

原理:是可以跨域的,而且在跨域腳本中可以直接回調當前腳本的函數

script標簽是可以載入異域的javaScript並執行的,通過預先設定好的callback函數來實現和母頁面的交互。它有一個大名,叫做JSONP跨域,JSONP是JSON with Padding的略稱。它是一個非官方的協議,明明是載入script,為啥和JSON扯上關系呢?原來就是這個callback函數,對它的使用有一個典型的方式,就是通過JSON來傳參,即將JSON數據填充進回調函數,這就是JSONP的JSON+Padding的含義。JSONP只支持GET請求。

❷ 跨域問題解決方法

跨域?他是瀏覽器的 同源策略 造成的,是瀏覽器對javascript施加的安全限制。所謂同源是指:域名、協議、埠均相同。

解決

原理:利用標簽具有可跨域的特性,可實現跨域訪問介面,需要後端的支持。

伺服器在收到請求後,解析參數,計算返還數據,輸出messagetow(data)字元串。

缺點:只能發送get請求,無法訪問伺服器的響應文本(單向請求),即只能獲取數據不能改數據。

通過ajax請求不同域的實現,底層不是靠XmlHttpRequest而是script,所以不要被這個方法給迷惑了。

在ajax請求中類型如果是type是get post,其實內部都只會用get,因為其跨域的原理就是用的動態載入script的src,所以我們只能把參數通過url的方式傳遞

其實jquery內部會轉化成

http://192.168.31.137/train/test/jsonpthree?callback=messagetow

然後動態載入http://192.168.1.114/yii/demos/test.php?backfunc=jQuery2030038573939353227615_1402643146875&action=aaron">

http://192.168.1.114/yii/demos/test.php?backfunc=jQuery2030038573939353227615_1402643146875&action=aaron"><script type="text/javascript" src=" http://192.168.31.137/train/test/jsonpthree?callback=messagetow "></script>

http://192.168.1.114/yii/demos/test.php?backfunc=jQuery2030038573939353227615_1402643146875&action=aaron">

http://192.168.1.114/yii/demos/test.php?backfunc=jQuery2030038573939353227615_1402643146875&action=aaron">

Cross-Origin Resource Sharing(CORS)跨域資源共享是一份瀏覽器技術的規范,提供了 Web 服務從不同域傳來沙盒腳本的方法,以避開瀏覽器的同源策略,確保安全的跨域數據傳輸。現代瀏覽器使用CORS在API容器如XMLHttpRequest來減少HTTP請求的風險來源。與 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。伺服器一般需要增加如下響應頭的一種或幾種:

跨域請求默認不會攜帶Cookie信息,如果需要攜帶,請配置下述參數:

​window.name通過在iframe(一般動態創建i)中載入跨域HTML文件來起作用。然後,HTML文件將傳遞給請求者的字元串內容賦值給window.name。然後,請求者可以檢索window.name值作為響應。

iframe標簽的跨域能力;

window.name屬性值在文檔刷新後依舊存在的能力(且最大允許2M左右)。

每個iframe都有包裹它的window,而這個window是top window的子窗口。 contentWindow 屬性返回<iframe>元素的Window對象。你可以使用這個Window對象來訪問iframe的文檔及其內部DOM。

​ HTML5新特性,可以用來向其他所有的 window 對象發送消息。需要注意的是我們必須要保證所有的腳本執行完才發送 MessageEvent,如果在函數執行的過程中調用了它,就會讓後面的函數超時無法執行。

​ 前提條件:這兩個域名必須屬於同一個基礎域名!而且所用的協議,埠都要一致,否則無法利用document.domain進行跨域,所以只能跨子域

​ 在 根域 范圍內,允許把domain屬性的值設置為它的上一級域。例如,在」aaa.xxx.com」域內,可以把domain設置為 「xxx.com」 但不能設置為 「xxx.org」 或者」com」。

​ 現在存在兩個域名aaa.xxx.com和bbb.xxx.com。在aaa下嵌入bbb的頁面,由於其document.name不一致,無法在aaa下操作bbb的js。可以在aaa和bbb下通過js將document.name = 'xxx.com';設置一致,來達到互相訪問的作用。

WebSocket protocol 是HTML5一種新的協議。它實現了瀏覽器與伺服器全雙工通信,同時允許跨域通訊,是server push技術的一種很棒的實現。相關文章,請查看: WebSocket 、 WebSocket-SockJS

**需要注意:**WebSocket對象不支持DOM 2級事件偵聽器,必須使用DOM 0級語法分別定義各個事件。

同源策略是針對瀏覽器端進行的限制,可以通過伺服器端來解決該問題,例如nginx

DomainA客戶端(瀏覽器) ==> DomainA伺服器 ==> DomainB伺服器 ==> DomainA客戶端(瀏覽器)

❸ 怎麼解決跨域問題

1、 通過jsonp跨域
JSONP(JSON with Padding:填充式JSON),應用JSON的一種新方法,
JSON、JSONP的區別:
1、JSON返回的是一串數據、JSONP返回的是腳本代碼(包含一個函數調用)
2、JSONP 只支持get請求、不支持post請求
(類似往頁面添加一個script標簽,通過src屬性去觸發對指定地址的請求,故只能是Get請求)

2、代理:
www..com/index.html需要調用www.sina.com/server.php,可以寫一個介面www..com/server.php,由這個介面在後端去調用www.sina.com/server.php並拿到返回值,然後再返回給index.html
3、PHP端修改header
header(『Access-Control-Allow-Origin:*』);//允許所有來源訪問
header(『Access-Control-Allow-Method:POST,GET』);//允許訪問的方式
4、document.domain
跨域分為兩種,一種xhr不能訪問不同源的文檔,另一種是不同window之間不能進行交互操作;
document.domain主要是解決第二種情況,且只能適用於主域相同子域不同的情況;
document.domain的設置是有限制的,我們只能把document.domain設置成自身或更高一級的父域,且主域必須相同。例如:a.b.example.com中某個文檔的document.domain可以設成a.b.example.com、b.example.com 、example.com中的任意一個,但是不可以設成c.a.b.example.com,因為這是當前域的子域,也不可以設成.com,因為主域已經不相同了。
兼容性:所有瀏覽器都支持;
優點:
可以實現不同window之間的相互訪問和操作;
缺點:
只適用於父子window之間的通信,不能用於xhr;
只能在主域相同且子域不同的情況下使用;
使用方式:
不同的框架之間是可以獲取window對象的,但卻無法獲取相應的屬性和方法。比如,有一個頁面,它的地址是http://www.example.com/a.html , 在這個頁面裡面有一個iframe,它的src是http://example.com/b.html, 很顯然,這個頁面與它裡面的iframe框架是不同域的,所以我們是無法通過在頁面中書寫js代碼來獲取iframe中的東西的:

<script type="text/javascript">
function test(){
var iframe = document.getElementById('ifame');
var win = document.contentWindow;//可以獲取到iframe里的window對象,但該window對象的屬性和方法幾乎是不可用的
var doc = win.document;//這里獲取不到iframe里的document對象
var name = win.name;//這里同樣獲取不到window對象的name屬性
}
</script>
<iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe>
這個時候,document.domain就可以派上用場了,我們只要把http://www.example.com/a.html 和 http://example.com/b.html這兩個頁面的document.domain都設成相同的域名就可以了。
1.在頁面 http://www.example.com/a.html 中設置document.domain:

<iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe>
<script type="text/javascript">
document.domain = 'example.com';//設置成主域
function test(){
alert(document.getElementById('iframe').contentWindow);//contentWindow 可取得子窗口的 window 對象
}
</script>
2.在頁面 http://example.com/b.html 中也設置document.domain:

<script type="text/javascript">
document.domain = 'example.com';//在iframe載入這個頁面也設置document.domain,使之與主頁面的document.domain相同
</script>
5、window.name
關鍵點:window.name在頁面的生命周期里共享一個window.name;
兼容性:所有瀏覽器都支持;
優點:
最簡單的利用了瀏覽器的特性來做到不同域之間的數據傳遞;
不需要前端和後端的特殊配製;
缺點:
大小限制:window.name最大size是2M左右,不同瀏覽器中會有不同約定;
安全性:當前頁面所有window都可以修改,很不安全;
數據類型:傳遞數據只能限於字元串,如果是對象或者其他會自動被轉化為字元串,如下;
這里寫圖片描述
使用方式:修改window.name的值即可;
6、postMessage
關鍵點:
postMessage是h5引入的一個新概念,現在也在進一步的推廣和發展中,他進行了一系列的封裝,我們可以通過window.postMessage的方式進行使用,並可以監聽其發送的消息;
兼容性:移動端可以放心用,但是pc端需要做降級處理
優點
不需要後端介入就可以做到跨域,一個函數外加兩個參數(請求url,發送數據)就可以搞定;
移動端兼容性好;
缺點
無法做到一對一的傳遞方式:監聽中需要做很多消息的識別,由於postMessage發出的消息對於同一個頁面的不同功能相當於一個廣播的過程,該頁面的所有onmessage都會收到,所以需要做消息的判斷;
安全性問題:三方可以通過截獲,注入html或者腳本的形式監聽到消息,從而能夠做到篡改的效果,所以在postMessage和onmessage中一定要做好這方面的限制;
發送的數據會通過結構化克隆演算法進行序列化,所以只有滿足該演算法要求的參數才能夠被解析,否則會報錯,如function就不能當作參數進行傳遞;
使用方式:通信的函數,sendMessage負責發送消息,bindEvent負責消息的監聽並處理,可以通過代碼來做一個大致了解;

Storage.prototype.sendMessage_ = function(type, params, fn) {
if (this.topWindow) {
this.handleCookie_(type, params, fn);
return;
}
var eventId = this.addToQueue_(fn, type);
var storageIframe = document.getElementById('mip-storage-iframe');
var element = document.createElement("a");
element.href = this.origin;
var origin = element.href.slice(0, element.href.indexOf(element.pathname) + 1);
storageIframe.contentWindow.postMessage({
type: type,
params: params,
eventId: eventId
}, origin);
}
Storage.prototype.bindEvent_ = function() {
window.onmessage = function (res) {
// 判斷消息來源
if (window == res.source.window.parent &&
res.data.type === this.messageType.RES &&
window.location.href.match(res.origin.host).length > 0) {
var fn = this.eventQueue[res.data.eventId];
fn && fn();
delete this.eventQueue[res.data.eventId];
// reset id
var isEmpty = true;
for (var t in this.eventQueue) {
isEmpty = false;
}
if (isEmpty) {
this.id = 0;
}
}
}.bind(this);
}

❹ 使用Openresty時配置解決跨域問題

實現系統架構簡圖如下:

一、編寫腳本

1、新建handle_cors.lua腳本文件

二、配置Nginx

1.配置nginx.conf信息

在server里對需要跨域的url添加

參考:https://blog.csdn.net/u010277446/article/details/78654491

踩坑:訪問Openresty伺服器時,使用postman、curl都是可以調通介面接收到正確響應的,但是在swagger-ui頁面中執行execute時,總是返回403,「TypeError: Failed to fetch」!使用如下所示針對nginx的跨域配置是無效的,只有根據上述方法,使用lua腳本設置才起作用。

#

# Wide-open CORS config for nginx

#

location / {

    if ($request_method = 'OPTIONS') {

        add_header 'Access-Control-Allow-Origin' '*';

        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';

        #

        # Custom headers and headers various browsers *should* be OK with but aren't

        #

        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';

        #

        # Tell client that this pre-flight info is valid for 20 days

        #

        add_header 'Access-Control-Max-Age' 1728000;

        add_header 'Content-Type' 'text/plain; charset=utf-8';

        add_header 'Content-Length' 0;

        return 204;

    }

❺ web前端面試題@二(Keeplive、V-show和v-if的區別、同源策略及跨域)

            在vue中,我們使用component內置組件或者vue-router切換視圖的時候,由於vue會主動卸載不使用的組件,所以我們不能保存組件之前的狀態,而我們經常能遇到需要保存之前狀態的需求,例如:搜索頁(保存搜索記錄),列表頁(保存之前的瀏覽記錄)等等。

            Keep-alive是一個vue的內置組件,它能將不活動的組件保存下來,而不是直接銷毀,當我們再次訪問這個組件的時候,會先從keep-alive中存儲的組件中尋找,如果有緩存的話,直接渲染之前緩存的,如果沒有的話,再載入對應的組件。

            作為抽象組件,keep-alive是不會直接渲染在DOM中的。

        Keep-alive提供了三種可選屬性

        Include-字元串或數組或正則表達式。只有名稱匹配的組件被緩存。

        Exclude -字元串或數組或正則表達式。名稱匹配的組件不會被緩存。

        Max -數字類型。表示最多可以緩存多少組件實例。

        Keep-alive提供了兩個生命鉤子,分別是activated與 deactivated。

        因為Keep-alive會將組件保存在內存中,並不會銷毀以及重新創建,所以不會重新調用組件的created等方法,需要用activated與deactivated這兩個生命鉤子來得知當前組件是否處於活動狀態。

        V-show有較高的渲染成本,

        V-if有較高的切換成本。

        V-if是真正的條件渲染,確保切換過程中條件內的事件監聽器和子組件適當的被銷毀和重建。

        V-show的元素始終被渲染並保存在dom中,操作的只是display屬性控制演示影藏。

        源(origin)—— 就是協議、域名和埠號。若地址裡面的協議、域名和埠號均相同則屬於同源。

        同源策略——同源策略是瀏覽器的一個安全功能,不同源的客戶端腳本在沒有明確授權的情況下,不能讀寫對方資源。所以a.com下的js腳本採用ajax讀取b.com裡面的文件數據是會報錯的。

    不受同源策略限制的

            1.頁面中的鏈接,重定向以及表單提交是不會受到同源策略限制的。

            2.跨域資源的引入是可以的。但是js不能讀寫載入的內容。如嵌入到頁面中的<script src="..."></script>,<img>,<link>,<iframe>等。

     跨域——只要協議、域名、埠號有一個不同就是跨域。

        跨域的原因?(只做了解)

跨域問題來源於JavaScript的同源策略,即只有 協議+主機名+埠號(如存在)相同,則允許相互訪問。為了防止某域名下的介面被其他域名下的網頁非法調用,是瀏覽器對JavaScript施加的安全限制。也就是說JavaScript只能訪問和操作自己域下的資源,不能訪問和操作其他域下的資源。跨域問題是針對JS和ajax的,html本身沒有跨域問題,比如a標簽、script標簽、甚至form標簽(可以直接跨域發送數據並接收數據)等。

       1、 Jsonp——

                利用script標簽可跨域的特點,在跨域腳本中可以直接回調當前腳本的函數。jsonp是一種常用的跨域手段,和反向代理,服務端做跨域處理相比,jsonp更顯得方便輕巧 jsonp的缺點只能發送get請求。因為script只能發送get請求需要後台配合。此種請求方式應該前後端配合,將返回結果包裝成callback(result)的形式。

       2、 Cors——

                伺服器設置HTTP響應頭中Access-Control-Allow-Origin值,解除跨域限制。CORS 是一個W3C標准,全稱是"跨域資源共享"(Cross-origin resource sharing),他允許瀏覽器向跨源伺服器發送XMLHttpRequest請求,從而克服 AJAX 只能同源使用的限制

                缺點是:目前所有最新瀏覽器都支持該功能,但是萬惡的IE不能低於10

Access-Control-Allow-Origin 這個欄位是必須的,表示接受那些域名的請求(*為所有)、Access-Control-Allow-Credentials 該欄位可選, 表示是否可以發送cookie、Access-Control-Expose-Headers 該欄位可選,XHMHttpRequest對象的方法只能夠拿到六種欄位: Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma ,如果想拿到其他的需要使用該欄位指定。

       3、反向代理(Reverse Proxy){前端獨立就能解決的跨域方案}——

    指以代理伺服器來接受internet上的連接請求,然後將請求轉發給內部網路上的伺服器,並將從伺服器上得到的結果返回給internet上請求連接的客戶端,此時代理伺服器對外就表現為一個反向代理伺服器。

    

❻ 用flash去連接socket伺服器,能不能不用crossdomain.xml文件

1、Loader載入圖片或者swf,只要不是載入到同個安全域,都不需要拉取crossdomain.xml。獲取在LoaderContext指定true,必須拉取。
但如果後續,要讀取圖片或者swf里邊內容,例如設置圖片smoothing或者draw,都需要拉取這個文件

如果文件不存在,會拋出安全沙箱沖突

可以手工security.loadPolicyFile,也可以在loader中設置loader.load(new URLRequest("http://xxxxxxxx/xxxx.jpg"),new LoaderContext(true));
但必須代碼中指定拉取策略文件才會去拉取,flash不會自動拉取。如果到了截圖的時候發現沒有拉取這個文件,就會報錯。

2、URLLoader請求的內容,flash會先自動請求crossdomain.xml,如果得到授權後再請求指定內容。

3、對於swf,如果要調用其他域名下的swf的腳本,還需要有Security.allowDomain()
http://help.adobe.com/zh_CN/AS2LCR/Flash_10.0/help.html?content=00001493.html

如果兩個 SWF 文件是同一個域提供,例如,http://mysite.com/movieA.swf 和
http://mysite.com/movieB.swf,則 movieA.swf 可以檢查和修改 movieB.swf 中的變數、對象、屬性、方法等,而且 movieB.swf 也可以對 movieA.swf 執行同樣的操作。這被稱為跨影片腳本編寫 或簡稱跨腳本編寫。
如果從不同的域提供兩個 SWF 文件(例如 http://mysite.com/movieA.swf 和
http://othersite.com/movieB.swf),則在默認情況下,Flash Player 既不允許 movieA.swf 編寫 movieB.swf 的腳本,也不允許 movieB.swf 編寫 movieA.swf 的腳本。通過調用 System.security.allowDomain(),一個 SWF 文件可授予其它域中的 SWF 文件編寫其腳本的許可權。這稱為跨域腳本編寫。通過調用 System.security.allowDomain("mysite.com"),movieB.swf 授予 movieA.swf 編寫 movieB.swf 的腳本的許可權。

使用 System.security.allowDomain() 建立的跨域許可權是不對稱的。在上一個示例中,movieA.swf 可以編寫 movieB.swf 的腳本,但 movieB.swf 無法編寫 movieA.swf 的腳本,這是因為 movieA.swf 未調用 System.security.allowDomain() 來授予 othersite.com 編寫 movieA.swf 的腳本的許可權。可以通過讓兩個 SWF 文件都調用 System.security.allowDomain() 來設置對稱許可權。

當然,有crossdomain.xml文件前提下,可以直接用urlloader載入回來,然後在loader.loadBytes,這樣就放到同一個程序域內了,沒有上述限制了。

❼ 跨域的幾種方法

瀏覽器出於安全方面的考慮,只允許客戶端與本域(同協議、同域名、同埠,三者缺一不可)下的介面交互。不同源的客戶端腳本在沒有明確授權的情況下,不能讀寫對方的資源,這被稱為同源策略。

而有時候,我們不得不在一個客戶端下訪問不同域中的資源,於是需要用到一些方法來避開瀏覽器的同源策略,這些方法被稱為跨域。
實現跨域有如下幾種方法:

JSONP(JSON with Padding)是數據格式JSON的一種使用模式,可以使網頁實現跨域請求。其原理主要利用了 HTML 的 script 標簽。由於 script 是採用開放策略,通過設置 src 引入不同域下的資源,所以可以通過 script 實現跨域,該方法需要後端支持。jsonp跨域的實現步驟如下:

下面來做個演示,首先為演示方便,將系統的hosts做如下修改:

以上例子最終實現了由example.a.com到example.b.com的跨域。應注意的是,因為 <script> 只能發送GET請求,所以jsonp只能實現GET請求的跨域。如果希望能實現其他請求的跨域,就可以用接下來介紹的一種方法——CORS。

CORS(全稱為:Cross-Origin Resouce Sharing)跨域資源共享,是一種通過ajax跨域請求資源的方法。瀏覽器將CORS請求分為兩大類,簡單請求(simple request)和非簡單請求(not-so-simple request,瀏覽器對這兩種請求的處理方式不一樣。如果請求滿足以下兩個條件,則為簡單請求。

簡單請求的實現方式即當用XMLHttpRequest發請求時,瀏覽器如果發現該請求不符合同源策略,會給該請求加上一個請求頭origin,origin用來說明本次請求來自哪個源(協議+域名+埠)。如果origin指定的源不在後台允許范圍內,後台會返回一個正常的HTTP響應,然後瀏覽器會發現該響應頭部信息不包含Access-Control-Allow-Origin欄位,然後拋出一個錯誤,該錯誤被XMLHttpRequest的onerror函數捕獲,響應被駁回,但因為該錯誤無法通過狀態碼識別,所以HTTP回應的狀態碼還是200。如果origin在後台允許范圍內,則伺服器返回的響應,會包含Access-Control-Allow-Origin:Origin(指定的源)信息,瀏覽器此時不會拋錯,響應能正常處理。
非簡單請求是是請求方法為PUT或DELETE,又或者Content-Type為application/json的對伺服器有特殊要求的請求。非簡單請求的CORS請求,會在正式通信前增加一次HTTP查詢,稱為預檢(preflight),詢問伺服器當前網頁所在域名是否在伺服器的許可名單中,如果在,則發出正式的XMLHttpRequest,之後就與簡單請求一樣,不在則報錯。
依舊用上面的例子。

最終實現的效果與第一個jsonp的例子一樣。

還有一種方式,就是通過降域來實現跨域。即通過設置document.domain的方式,將兩個域名的domain設置為一個,如對於a.example.com和b.example.com,可以通過js設置 document.domain = "example.com" ,實現跨域。
做個演示,假設在 http://a.example.com:8080 下有一個a.html文件,其中a.html中有一個 iframe ,它的 src 為 http://b.example.com:8080/b.html 。

用降域方法實現跨域操作簡單,但是有一些缺點。比如域名只能往下設置,不能回去,比如從example.com回到a.example.com。同時如果一個子域名被攻擊,多個被降域的域名都會被連帶攻擊,有很大的安全風險。

postMessage是一個web API,可以實現跨域通信。 window.postMessage() 被調用時,會在所有頁面腳本執行完畢後,向目標窗口派發一個 MessageEvent 消息。語法如下:

MessageEvent 具有如下屬性:

用一個與上面降域類似的例子來做演示。同樣有兩個頁面a.html和b.html,a.html中的 iframe 的 src 指向b.html。

最終實現a.html與b.html通信效果如下:

使用postMessage方法應注意的是,如果不希望從其他網站接收message,那麼不要為message事件添加任何監聽器。如果確實希望接收其他網站的message,那麼應該始終使用origin和source屬性來驗證發件人的身份,以免被惡意的網站攻擊。

以上就是幾種常見的跨域方法,各有優劣,且各自都有一定的安全問題,在日常應用中,需要有針對性的使用,對可能的安全風險採取相應措施。

❽ vue 如何實現跨域

跨域問題是因為瀏覽器的同源策略引起的,一種瀏覽器的安全機制,要求 協議,域名,埠 ,都要一致!

出於瀏覽器的同源策略限制,瀏覽器會拒絕跨域請求。

什麼叫跨域?非同源請求,均為跨域。名詞解釋:同源 —— 如果兩個頁面擁有相同的協議(protocol),埠(port)和主機(host),那麼這兩個頁面就屬於同一個源(origin)。

怎麼解決跨域?最常用的三種方式: JSONP、CORS、postMessage

jsonp,只支持get,不支持post,需要調用前端和被調用後端配合(比較常用)

後端HttpClient進行轉發,兩次請求,效率低,安全(類似Nginx反向代理)

服務端設置響應頭,允許跨域,適於小公司快速解決問題

Nginx搭建API介面網關

Zuul搭建API介面網關

後四種都屬於服務端設置,對於目前還是一個純前端的我來說,先把前端的搞懂再說,所以在此只說前端

jsonp工作原理理解

jsonp實際上是通過動態插入js的方式實現的跨域,因為通過script標簽引入js文件沒有跨域一說

web客戶端通過調用腳本的方式去調用跨域服務端動態生成的js文件(一般以json為後綴),同時傳遞一個callback參數給服務端,服務端以這個參數名為函數名,調用此函數以參數的形式將數據傳到web端,這樣就實現了前端跨域請求服務端數據。

【JSONP的優缺點】

優點:兼容性好(兼容低版本IE)

缺點:1.JSONP只支持GET請求; 2.XMLHttpRequest相對於JSONP有著更好的錯誤處理機制

CORS :是W3C 推薦的一種新的官方方案,能使伺服器支持 XMLHttpRequest 的跨域請求。CORS 實現起來非常方便,只需要增加一些 HTTP 頭,讓伺服器能聲明允許的訪問來源。

postMessage : window.postMessage(message,targetOrigin) 方法是html5新引進的特性,可以使用它來向其它的window對象發送消息,無論這個window對象是屬於同源或不同源,目前IE8+、FireFox、Chrome、Opera等瀏覽器都已經支持 window.postMessage方法。

❾ 手機APP和web服務端 跨域問題

跨域問題來源於JavaScript的同源策略,即只有 協議+主機名+埠號 (如存在)相同,則允許相互訪問。也就是說JavaScript只能訪問和操作自己域下的資源,不能訪問和操作其他域下的資源。
在以前,前端和後端混雜在一起, 比如JavaScript直接調用同系統裡面的一個Httphandler,就不存在跨域的問題,但是隨著現代的這種多種客戶端的流行,比如一個應用通常會有Web端,App端,以及WebApp端,各種客戶端通常會使用同一套的後台處理邏輯,即API, 前後端分離的開發策略流行起來,前端只關注展現,通常使用JavaScript,後端處理邏輯和數據通常使用WebService來提供json數據。一般的前端頁面和後端的WebService API通常部署在不同的伺服器或者域名上。這樣,通過ajax請求WebService的時候,就會出現同源策略的問題。
需要說明的是,同源策略是JavaScript裡面的限制,其他的編程語言,比如在C#,Java或者iOS等其他語言中是可以調用外部的WebService,也就是說,如果開發Native應用,是不存在這個問題的,但是如果開發Web或者Html5如WebApp,通常使用JavaScript ajax對WebService發起請求然後解析返回的值,這樣就可能存在跨域的問題。
一般的,很容易想到,將外部的資源搬到同一個域上就能解決同源策略的限制的。即在Web網站上同時開發一個Http服務端頁面,所有JavaScript的請求都發到這個頁面上來,這個頁面在內部使用其他語言去調用外部的WebService。即添加一個代理層。這種方式可以解決問題,但是不夠直接和高效。
目前,比較常見的跨域解決方案包括JSONP (JSON with padding)和CORS (Cross-origin resource sharing )。一些解決方案需要客戶端和服務端配合如JSOP,一些則只需要服務端配合處理比如CORS。下面分別介紹這兩種跨域方案,以及服務端WebService如何支持這兩種跨域方案。
JSONP以及WebService的支持
同源策略下,某個伺服器是無法獲取到伺服器以外的數據,但是html裡面的img,iframe和script等標簽是個例外,這些標簽可以通過src屬性請求到其他伺服器上的數據。而JSONP就是通過script節點src調用跨域的請求。
當我們向伺服器提交一個JSONP的請求時,我們給服務傳了一個特殊的參數,告訴服務端要對結果特殊處理一下。這樣服務端返回的數據就會進行一點包裝,客戶端就可以處理。
舉個例子,服務端和客戶端約定要傳一個名為callback的參數來使用JSONP功能。比如請求的參數如下:
http://www.example.net/sample.aspx?callback=mycallback

如果沒有後面的callback參數,即不使用JSONP的模式,該服務的返回結果可能是一個單純的json字元串,比如:
{ foo : 'bar' }

如果和服務端約定jsonp格式,那麼服務端就會處理callback的參數,將返回結果進行一下處理,比如處理成:
mycallback({ foo : 'bar' })

可以看到,這其實是一個函數調用,比如可以實現在頁面定義一個名為mycallback的回調函數:
mycallback = function(data)
{
alert(data.foo);
};

現在,請求的返回值回去觸發回調函數,這樣就完了了跨域請求。
如果使用ServiceStack創建WebService的話,支持Jsonp方式的調用很簡單,只需要在AppHost的Configure函數裡面注冊一下對響應結果進行過濾處理即可。
/// <summary>
/// Application specific configuration
/// This method should initialize any IoC resources utilized by your web service classes.
/// </summary>
/// <param name="container"></param>
public override void Configure(Container container)
{
ResponseFilters.Add((req, res, dto) =>
{
var func = req.QueryString.Get("callback");
if (!func.isNullOrEmpty())
{
res.AddHeader("Content-Type", ContentType.Html);
res.Write("<script type='text/javascript'>{0}({1});</script>"
.FormatWith(func, dto.ToJson()));
res.Close();
}
});
}

JSONP跨域方式比較方便,也支持各種較老的瀏覽器,但是缺點很明顯,他只支持GET的方式提交,不支持其他Post的提交,Get方式對請求的參數長度有限制,在有些情況下可能不滿足要求。所以下面就介紹一下CORS的跨域解決方案。
CORS跨域及WebService的支持
先來看一個例子,我們新建一個基本的html頁面,在裡面編寫一個簡單的是否支持跨域的小腳本,如下:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>AJAX跨域請求測試</title>
</head>
<body>
<input type='button' value='開始測試' onclick='crossDomainRequest()' />
<div id="content"></div>

<script type="text/javascript">
//<![CDATA[
var xhr = new XMLHttpRequest();
var url = 'http://localhost:8078/json/ShopUserLogin';
function crossDomainRequest() {
document.getElementById("content").innerHTML = "開始……";
if (xhr) {
xhr.open('POST', url, true);
xhr.onreadystatechange = handler;
xhr.send();
} else {
document.getElementById("content").innerHTML = "不能創建 XMLHttpRequest";
}
}

function handler(evtXHR) {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
var response = xhr.responseText;
document.getElementById("content").innerHTML = "結果:" + response;
} else {
document.getElementById("content").innerHTML = "不允許跨域請求。";
}
}
else {
document.getElementById("content").innerHTML += "<br/>執行狀態 readyState:" + xhr.readyState;
}
}
//]]>
</script>

</body>
</html>

然後保存為本地html文件,可以看到,這個腳本中,對本地的服務http://localhost:1337/json/Hello 發起了一個請求, 如果使用chrome 直接打開,會看到輸出的結果,不允許跨域請求。 在javascript控制台程序中同樣可以看到錯誤提示:

那麼如果在返回響應頭header中注入Access-Control-Allow-Origin,這樣瀏覽器檢測到header中的Access-Control-Allow-Origin,則就可以跨域操作了。
同樣,如果使用ServcieStack,在很多地方可以支持CORS的跨域方式。最簡單的還是在AppHost的Configure函數裡面直接寫入:
/// <summary>
/// Application specific configuration
/// This method should initialize any IoC resources utilized by your web service classes.
/// </summary>
/// <param name="container"></param>
public override void Configure(Container container)
{
this.AddPlugin(new CorsFeature());
}

這樣就可以了,相當於使用默認的CORS配置:
CorsFeature(allowedOrigins:"*",
allowedMethods:"GET, POST, PUT, DELETE, OPTIONS",
allowedHeaders:"Content-Type",
allowCredentials:false);

如果僅僅允許GET和POST的請求支持CORS,則只需要改為:
Plugins.Add(new CorsFeature(allowedMethods: "GET, POST"));

當然也可以在AppHost的Config裡面設置全局的CORS,如下:
/// <summary>
/// Application specific configuration
/// This method should initialize any IoC resources utilized by your web service classes.
/// </summary>
/// <param name="container"></param>
public override void Configure(Container container)
{

base.SetConfig(new EndpointHostConfig
{
GlobalResponseHeaders = {
{ "Access-Control-Allow-Origin", "*" },
{ "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS" },
{ "Access-Control-Allow-Headers", "Content-Type" },
},
});
}

現在運行WebService,使用postman或者Chrome調用這個請求,可以看到返回的值頭文件中,已經加上了響應頭,並且可以正常顯示返回結果了:

CORS使用起來簡單,不需要客戶端的額外處理,而且支持Post的方式提交請求,但是CORS的唯一一個缺點是對客戶端的瀏覽器版本有要求,支持CORS的瀏覽器機器版本如下:

總結
本文介紹了JavaScript中的跨域基本概念和產生的原因,以及如何解決跨域的兩種方法,一種是JSONP 一種是 CORS,在客戶端Javascript調用服務端介面的時候,如果需要支持跨域的話,需要服務端支持。JSONP的方式就是服務端對返回的值進行回調函數包裝,他的優點是支持眾多的瀏覽器, 缺點是僅支持Get的方式對服務端請求。另一種主流的跨域方案是CORS,他僅需要服務端在返回數據的時候在相應頭中加入標識信息。這種方式非常簡便。唯一的缺點是需要瀏覽器的支持,一些較老的瀏覽器可能不支持CORS特性。
跨域支持是創建WebService時應該考慮的一個功能點,希望本文對您在這邊面有所幫助,文中是使用ServiceStack來演示跨域支持的,如果您用的WCF的話,知道跨域原理的前提下,實現跨域應該不難。

參考資料:
https://github.com/ServiceStack/ServiceStack/wiki/Customize-HTTP-Responses
https://github.com/ServiceStack/ServiceStack/wiki/Request-and-response-filters
http://stackoverflow.com/questions/8211930/servicestack-rest-api-and-cors
http://stackoverflow.com/questions/15224038/rename-callback-parameter-for-jsonp

❿ HTML5 script 標簽的 crossorigin 屬性到底有什麼用

最近 Bootstrap 4 已經正式發布了,可能已經有愛嘗鮮的小夥伴在 alpha 階段就嘗試過 BS4。不過今天要說的不是 BS4,而是官網里引入 BS4 框架依賴的 jQuery 的代碼:

XHTML
1
2
3
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous"></script>

看起來比以前的寫法復雜好多的樣子。先不著急慢慢看,多了一個 integrity 屬性,看值的樣子就知道是用來驗證文件完整性的。另外還有一個 crossorigin 屬性……怎麼?直接通過 script 標簽載入網站外 JS 資源也要開始考慮跨域的問題了嗎?

這里不討論 script 里 crossorigin 屬性怎麼用,以及伺服器端如何支持此屬性,MDN 上的文檔已經說得很清楚。

不知道大家對此新屬性的感覺如何,我的第一感覺是:新加了這么一個屬性,難道是以前 script 不用 crossorigin 屬性的時候,會出什麼問題嗎?到底可能會出什麼問題呢?

從谷歌的結果來看,比較一致的說法是,引入跨域的腳本(比如用了 apis.google.com 上的庫文件),如果這個腳本有錯誤,因為瀏覽器的限制(根本原因是協議的規定),是拿不到錯誤信息的。當本地嘗試使用 window.onerror 去記錄腳本的錯誤時,跨域腳本的錯誤只會返回 Script error。

script error

但 HTML5 新的規定,是可以允許本地獲取到跨域腳本的錯誤信息,但有兩個條件:一是跨域腳本的伺服器必須通過 Access-Controll-Allow-Origin 頭信息允許當前域名可以獲取錯誤信息,二是當前域名的 script 標簽也必須指明 src 屬性指定的

熱點內容
ss怎麼用安卓 發布:2024-03-28 18:51:39 瀏覽:687
腳本注入到其他軟體運行 發布:2024-03-28 18:30:02 瀏覽:720
網易我的世界皮膚能用到伺服器嗎 發布:2024-03-28 18:24:44 瀏覽:804
access資料庫數據類型 發布:2024-03-28 18:16:04 瀏覽:301
安卓界面如何變成蘋果手機界面 發布:2024-03-28 18:07:17 瀏覽:742
方舟手游如何卡安卓大廳會員 發布:2024-03-28 17:52:37 瀏覽:241
空域銳化演算法 發布:2024-03-28 17:52:32 瀏覽:500
虎牙安卓版是什麼意思 發布:2024-03-28 17:43:10 瀏覽:861
電腦改成雲伺服器 發布:2024-03-28 17:37:50 瀏覽:266
文件夾審計 發布:2024-03-28 17:08:20 瀏覽:242