A. web前端跨域的一些解決方案
沒有歸納之前對跨域的一些說法是模糊的,什麼jsonp啊,跨域原理啊,心裡只有一個大概的說法,知道這個東西,然後用的時候直接網路Ctrl+C,後來閑下來決定整理一波這些知識點,需知其所以然。
那麼,其實這是瀏覽器對我們的一種保護機制,把壞人擋在門外。那麼,問題來了,我們怎麼確定門外的人到底是好人還是壞人呢?瀏覽器關上了壞人的一扇門,留給了我們好人一扇窗。
JSONP跟JSON沒有關系..就好像JavaScript和Java一樣
瀏覽器對script、img(這些標簽的請求方式都是 GET ,所以jsonp不支持 POST )這種標簽沒有限制,我們就可以這樣干
因此,實現CORS通信的關鍵是伺服器。只要伺服器實現了CORS介面,就可以跨源通信。
伺服器端對於CORS的支持,主要就是通過設置 Access-Control-Allow-Origin 來進行的。如果瀏覽器檢測到相應的設置,就可以允許Ajax進行跨域的訪問。 更多有關跨域資源共享 CORS 的知識
瀏覽器中可以查看對應的響應頭,舉個例子,如下
服務端允許CORS,服務端需要針對介面設置的一系列響應頭 (Response Headers)
1.簡單請求
目前大多數情況都採用這種方式。簡單請求只需要設置 Access-Control-Allow-Origin 即可。滿足以下兩個條件,就屬於簡單請求。
2.非簡單請求
非簡單請求會發出一次預檢測請求,返回碼是204,預檢測通過才會真正發出請求,這才返回200。來看栗子:
非簡單請求需要根據不同情況配置不同的響應頭,一系列響應頭配置項見上方
這個說法相信不陌生,我們依然使用前端域名請求,然後有一個 中介商---代理 把這個請求轉發到真正的後端域名上,那也就不存在跨域問題了。
比較普遍的Nginx,簡單的配置一下就可以了。了解更多的配置信息: nginx詳解
然後前端這邊的請求地址是 http://localhost:9099/api/xxx ,然後Nginx監聽到地址是 localhost:9099/api 的請求,就幫我們轉發到真正的服務端地址 http://.com
CORS與JSONP的使用目的相同,但是比JSONP更強大。JSONP只支持GET請求,CORS支持所有類型的HTTP請求。JSONP的優勢在於支持老式瀏覽器,以及在服務端同意jsonp方式時,可以向不支持CORS的網站請求數據。Nginx可以說是最方便的,不過需要部署Nginx才行,需要對伺服器有一定的理解,不太適合剛入門的同學,當然也可以請後台同學幫忙部署。
window.postMessage(data,origin) 是 HTML5 的一個介面,專注實現不同窗口不同頁面的跨域通訊。
現在是這么一個情況,由於同源策略的限制下, a.html 不能操作iframe( b.html )裡面的dom,那麼使用postMessage就可以解決這一情況
然後 b.html 頁面通過message事件監聽並接受消息:
這種方式只適合主域名相同,但子域名不同的iframe跨域。
比如主域名是 http://.com/:8888 ,子域名是 http://child..com/:8888 ,這種情況下給兩個頁面設置相同的document.domain即document.domain = .com 就可以訪問各自的window對象了。
前端跨域整理
不要再問我跨域的問題了
B. 前端跨域解決 (vscode live server proxy 代理)
這個顯然是處理前端跨域最優的方法了,在此記錄下來方便以後使用,附送scss 轉 css
使用 vscode IDE作為編寫工具
1.搜索並載入 vscode 插件 live server
2.要文件根目錄創建 ".vscode" 目錄
3.在 .vscode 目錄下創建settings.json
4.proxUri 為代理的目標地址
5.baseUri 識別代理的符號 (如下例中 baseUri: '/api', 則以"/api"開頭的網路請求都將被識別為需要代理轉發的地址,並把 『/api』重寫為空"")
1.ajax請求會受到瀏覽器同源策略的限制(同源 = 域名 + 埠 都一致)
2.ajax請求默認攜帶 同源下的所有cookie, 如果不做限制 a 去請求 b 的時候就等於把a所有的cookie 都告訴b。
3.同源下: 張三的網站只能訪問張三的內容如鞋子衣服吃飯等等,如果想訪問李四的,瀏覽器就不讓你幹了。如果充許這么乾的話,張三的cookie隱私將直接暴露給李四,李四有可能幹一些不懷好意的事情。
4.跨域情況:張三把錢都放在李四那裡,現在張三想去李四那邊取錢,這時候就需要跨域了。
5.跨域怎麼解決呢?接下來把解決問題的思路簡單描繪一下。
5.1:李四告訴全世界說我對錢不感興趣,只要我有,你們所有人都隨便來取。因此,當瀏覽器看到張三要取錢的人是李四這種慈善家,就不再攔著你了。
5.2:李四不是慈善家怎麼辦?於是張三這個時候就很討厭瀏覽器,想了個辦法繞過瀏覽器,然後另外找了個代理去跟李四取錢
5.2.1: 問題是繞過瀏覽器?怎麼繞呢? 於是張三自己建了個伺服器,每次要跟李四取錢的時候就欺騙瀏覽器說我要跟自己的伺服器取錢,瀏覽器這個時候也就不再攔著你了
5.2.2:當張三自己的伺服器接收到跟李四取錢任務後,就以proxy代理的身份向李四取錢,取完錢之後再通過瀏覽器給了張三
5.2.3:vscode 中的live server 插件裡面就這個代理向李四取錢的代理伺服器功能,本文settings.json 中包含了配置信息
6.當然還有一些很多牛叉的解決跨域的方法。若有興趣的同學可以一起研究探討。
C. 前端跨域如何解決
什麼是跨域?
跨域是通俗的說是從一個域名去請求另一個域名的資源。比如從 www..com 頁面去請求 www.taobao.com 的資源。
跨域嚴格一點來說:兩個域名只要協議,域名,埠中只要有一個不同,就被成為跨域
瀏覽器為什麼要限制跨域?
只有同域才可以拿到存在cookie中的信息,防止壞人隨意拿到我們的信息去做壞事
在團隊的配置中,我們為了減少前端對後端的依賴,提高開發效率,使前後端職責更清晰等等因素,我們不得不面對跨域的問題,那我們該怎麼解決呢?
1、 JSONP
原理:瀏覽器對script的資源引用沒有同源限制,同時資源載入到頁面後會立即執行,所以通過動態插入script標簽即可達到跨域的請求
特點:數據為json格式
缺點:不能post
2、 CORS
原理 : cors(Cross-Origin Resource Sharing)是 W3C CORS 工作草案 ,它定義了在跨域訪問資源時瀏覽器和伺服器之間如何通信。CORS背後的基本思想是使用自定義的HTTP頭部允許瀏覽器和伺服器相互了解對方,從而決定請求或響應成功與否
特點 :是 JSONP 模式的現代版。支持更多的請求方式,XMLHttpRequest
缺點:需後端配合修改,現代瀏覽器支持cors,老瀏覽器依舊要用JSONP
3、 PROXY
原理:proxy代理用於將請求攔截,然後通過伺服器來發送請求,然後再將請求的結果傳遞給前端
node通常用 node-http-proxy 即可
proxy太通用了,weblack-dev-server里已集成,使用時直接配置即可 webpack-dev-server proxy代理
D. 後端解決前端跨域請求問題
場景:前後端分離,頁面和後端項目部署在不同伺服器,出現請求跨域問題。
原因:CORS:跨來源資源共享(CORS)是一份瀏覽器技術的規范,提供了 Web 服務從不同網域傳來沙盒腳本的方法,以避開瀏覽器的同源策略,是 JSONP 模式的現代版。與 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。用 CORS 可以讓網頁設計師用一般的 XMLHttpRequest,這種方式的錯誤處理比JSONP要來的好,JSONP對於 RESTful 的 API 來說,發送 POST/PUT/DELET 請求將成為問題,不利於介面的統一。但另一方面,JSONP 可以在不支持 CORS 的老舊瀏覽器上運作。不過現代的瀏覽器(IE10以上)基本都支持 CORS。
預檢請求(option):在 CORS 中,可以使用 OPTIONS 方法發起一個預檢請求(一般都是瀏覽檢測到請求跨域時,會自動發起),以檢測實際請求是否可以被伺服器所接受。預檢請求報文中的 Access-Control-Request-Method 首部欄位告知伺服器實際請求所使用的 HTTP 方法;Access-Control-Request-Headers 首部欄位告知伺服器實際請求所攜帶的自定義首部欄位。伺服器基於從預檢請求獲得的信息來判斷,是否接受接下來的實際請求。
解決方案:
1、創建一個過濾器,過濾options請求。
package com.biz.eisp.sci.util;
import org.apache.commons.httpclient.HttpStatus;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 解決跨域問題
*
*/
public class CorsFilterimplements Filter {//filter 介面的自定義實現
public void init(FilterConfig filterConfig)throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpServletRequest request = (HttpServletRequest) servletRequest;
response.setHeader("Access-Control-Allow-Origin", "*");
if ("OPTIONS".equals(request.getMethod())){//這里通過判斷請求的方法,判斷此次是否是預檢請求,如果是,立即返回一個204狀態嗎,標示,允許跨域;預檢後,正式請求,這個方法參數就是我們設置的post了
response.setStatus(HttpStatus.SC_NO_CONTENT); //HttpStatus.SC_NO_CONTENT = 204
response.setHeader("Access-Control-Allow-Methods", "POST, GET, DELETE, OPTIONS, DELETE");//當判定為預檢請求後,設定允許請求的方法
response.setHeader("Access-Control-Allow-Headers", "Content-Type, x-requested-with"); //當判定為預檢請求後,設定允許請求的頭部類型
response.addHeader("Access-Control-Max-Age", "1"); // 預檢有效保持時間
}
filterChain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
2、修改web.xml文件
<filter>
<filter-name>cors</filter-name>
<filter-class>com.biz.eisp.sci.util.CorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cors</filter-name>
<url-pattern>/* </url-pattern>
</filter-mapping>
3、spring-mvc.xml添加HttpRequestHandlerAdapter http請求處理器適配器。
HttpRequestHandlerAdapter作為HTTP請求處理器適配器僅僅支持對HTTP請求處理器的適配。它簡單的將HTTP請求對象和響應對象傳遞給HTTP請求處理器的實現,它並不需要返回值。它主要應用在基於HTTP的遠程調用的實現上。
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
E. 跨域怎麼解決
問題一:如何解決跨域問題 特別注意兩點:
第一,如果是協議和埠造成的跨域問題「前台」是無能為力的,
第二:在跨域問題上,域僅僅是通過「URL的首部」來識別而不會去嘗試判斷相同的ip地址對應著兩個域或兩個域是否在同一個ip上。
「URL的首部」指window.location.protocol +window.location.host,也可以理解為「Domains, protocols and ports must match」。
2. 前端解決跨域問題
1> document.domain + iframe (只有在主域相同的時候才能使用該方法)
1) 在a/a中:
復制代碼
document.domain = 'a';
var ifr = document.createElement('iframe');
ifr.src = 'script.a/b';
ifr.display = none;
document.body.appendChild(ifr);
ifr.onload = function(){
var doc = ifr.contentDocument || ifr.contentWindow.document;
在這里操作doc,也就是b
ifr.onload = null;
};
復制代碼
2) 在script.a/b中:
document.domain = 'a';
2> 動態創建script
這個沒什麼好說的,因為script標簽不受同源策略的限制。
復制代碼
function loadScript(url, func) {
var head = document.head || document.getElementByTagName('head')[0];
var script = document.createElement('script');
script.src = url;
script.onload = script.onreadystatechange = function(){
if(!this.readyState || this.readyState=='loaded' || this.readyState=='plete'){
func();
script.onload = script.onreadystatechange = null;
}
};
head.insertBefore(script......>>
問題二:如何解決跨域問題 由 於此前很少寫前端的代碼(哈哈,不合格的程序員啊),最近項目中用到json作為系統間交互的手段,自然就伴隨著眾多ajax請求,隨之而來的就是要解決 ajax的跨域問題。本篇將講述一個小白從遇到跨域不知道是跨域問題,到知道是跨域問題不知道如何解決,再到解決跨域問題,最後找到兩種方法解決ajax 跨域問題的全過程。
不知是跨域問題
起 因是這樣的,為了復用,減少重復開發,單獨開發了一個用戶許可權管理系統,共其他系統獲取認證與授權信息,暫且稱之為A系統;調用A系統以B為例。在B系統 中稿虧用ajax調用A系統系統的介面(數據格式為json),當時特別困惑,在A系統中訪問相應的url可正常回返json數據,但是在B系統中使用 ajax請求同樣的url則一點兒反應都沒有,好像什麼都沒有發生一樣。這樣反反復復改來改去好久都沒能解決,於是求救同事,提醒可能是ajax跨域問 題,於是就將這個問題當做跨域問題來解決了。
知跨域而不知如何解決
知道問題的確切原因,剩鍵舉神下的就是找到解決問題的方法了。google了好久,再次在同事的指點下知道jQuery的ajax有jsonp這樣的屬性可以用來解決跨域的問題。
找到一種解決方式
現在也知道了怎樣來解決跨域問題,餘下的就是實現的細節了。實現的過程中錯誤還是避免不了的。由於不了解json和jsonp兩種格答純式的區別,也犯了錯誤,google了好久才解決。
首先來看看在頁面中如何使用jQuery的ajax解決跨域問題的簡單版:
復制代碼
$(document).ready(function(){
var url='localhost:8080/...upById
+?id=1&callback=?';
$.ajax({
url:url,
dataType:'jsonp',
processData: false,
type:'get',
success:function(data){
alert(data.name);
},
error:function(XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest.status);
alert(XMLHttpRequest.readyState);
alert(textStatus);
}});
});
復制代碼
這樣寫是完全沒有問題的,起先error的處理函數中僅僅是alert(「error」),為了進一步弄清楚是什麼原因造成了錯誤,故將處理函數變 為上面的實現方式。最後一行alert使用為;parsererror。百思不得其解,繼續google,最終還是在萬能的stackoverflow找 到了答案,鏈接在這里。原因是jsonp的格式與json格式有著細微的差別,所以在server端的代碼上稍稍有所不同。
比較一下json與jsonp格式的區別:
json格式:
{
message&q......>>
問題三:跨域是指什麼,因為什麼引起的?有哪些解決方案?web前端知識 跨域是指 不同域名之間相互訪問 例如 我的電腦上有2個伺服器 192.168.0.11 192.168.0.12 如果第一個伺服器上的頁面要訪問第二個伺服器 就叫做跨域 或者 要訪問xxx 也是不同域名 也是跨域
HTML5 里有個window.postMessage 方法,支持跨域訪問,詳情可以參考
webhek/window-postmessage-api
如果你的程序在伺服器上,也可以進行相應的操作來完成跨域訪問
純手打 有問題歡迎咨詢
問題四:如何解決跨域問題 打開IE瀏覽器,在工具菜單下選擇Internet選項,打開Internet選項卡
切換到安全選項卡下,點擊可信站點,然後單擊站點按鈕
可信站點窗口輸入網址到可信站點的區域,點擊添加按鈕,網址則會添加到網站列表下,最後關閉可信站點窗口
還是在安全選項卡下的可信站點,點擊自定義級別
打開受信任的站點區域窗口,找到跨域瀏覽窗口和框架選擇啟用
在當前窗口中繼續往下翻,通過域訪問數據源也選擇啟用,點擊確定關閉受信任的站點區域窗口
在Internet窗口也點擊確定按鈕,同時關閉瀏覽器
在請求的js腳本中添加是否允許跨域訪問的許可權,jQuery.support.cors默認值為true,則代表允許;反之,不允許。設置完成,重新打開瀏覽器驗證即可
問題五:$跨域請求怎麼解決 post請求進行跨域
angularjs內置封裝了類ajax的網路服務$,所以實現了依賴外部插件來完成完整的前後端分離方案
$scope.main = {
getData: function () {
$({
method: 'POST',
url: 'localhost:8000',
headers: {
'Content-Type' : 'application/x--form-urlencoded'
},
data: {
myUrl: 'c.m.163/...0'
}
}).then(function success(result) {
數據請求成功
console.log(result.data);
},function error(err) {
數據請求失敗
console.log(err);
});
}
};
注意:表面上是向$中傳入了一個回調函數提供相應時調用,實際是返回了一個promise對象,angular1.2以上的版本對$進行了優化
優化後:
$scope.main = {
getData: function () {
var myUrl = 'c.m.163/...0';
var url = 'localhost:8000';
var promise = $({
method: 'POST',
url: url,
headers: {
'Content-Type' : 'text/plain'
......>>
問題六:如何解決跨域問題 關於跨域名問題還是問題么,這方面的解決實踐非常多,今天我就舊話重提把我所知道的通過幾個應用場景來分別總結一下(轉帖請註明出處:blog.csdn/lenel)
先說明一點:我說的某某域名在您的控制下的意思是這個域名下的網頁由您來負責開發內部的JavaScript
場景一:將bbs.xxx的頁面用iframe嵌入到xxx的中,如何在iframe內外使用js通信(轉帖請註明出處:blog.csdn/lenel)
一級域名都是xxx 這個域名一定是在您的控制下,所以你只要在兩個頁面中同時升級域名即可
在父窗口和iframe內部分別加上js語句:document.domain=xxx;
之後2個頁面就等於在同一域名下,通過window.parent oIframe.contentDocument就可以相互訪問,進行無障礙的JS通信
在新浪、淘寶等很多頁面都能找到這樣的語句。不過document.domain不可以隨便指定,只能向上升級,從bbs.xxx升級到yyy肯定會出錯
場景二:將yyy的頁面用iframe嵌入到xxx的中,兩個域名都在您的控制下,如何在iframe內外進行一定的數據交流(轉帖請註明出處:blog.csdn/lenel)
你可以通過相互改變hash值的方式來進行一些數據的通信
這里的實現基於如下技術要點:
1、父窗口通過改變子窗口的src中的hash值把一部分信息傳入,如果src只有hash部分改變,那麼子窗口是不會重新載入的。
2、
子窗口可以重寫父窗口的location.href,但是注意這里子窗口無法讀取而只能重寫location.href所以要求前提是您控制兩個域名,知
道當前父窗口的location.href是什麼並寫在子窗口內,這樣通過parent.location.href =
已知的父窗口的href+#+hash。這樣父窗口只有hash改變也不會重載。
3、上面兩步分別做到了兩個窗口之間的無刷新數據通知,
那麼下面的來說如何感知數據變化。標准中沒有相關規定,所以當前的任意瀏覽器遇到location.hash變化都不會觸發任何javaScript事
......>>
問題七:如何解決javascript的跨域問題 一般是用iframe設置
document.domain = 'a';var ifr = document.createElement('iframe');ifr.src = 'a/index';ifr.style.display = 'none';document.body.appendChild(ifr);ifr.onload = function(){ var doc = ifr.contentDocument || ifr.contentWindow.document; console.log(doc.documentElement.innetHTML);};然後HTML5新特性有 ,postMessage
function Init () { if (window.addEventListener) { all browsers except IE before version 9 window.addEventListener (message, OnMessage, false); } else { if (window.attachEvent) { IE before version 9 window.attachEvent(onmessage, OnMessage); } } } function GetState () { var frame = document.getElementById (myFrame); var message = getstate;參數if (frame.contentWindow.postMessage) { 傳遞的參數,後面是傳遞的你的跨域域名frame.contentWindow.postMessage (message, *); } } function OnMessage (event) { console.log(event.data);} document.body.onload=function(){Init();GetState();};
問題八:如何解決跨域問題 VPN或者域名
問題九:如何解決請求跨域的問題 jsonp 是寫 script 標簽,只能滿足 get 請求。跨域 post 的話,IE8 及以上和其他主流瀏覽器可以用 window.postMessage 來實現,也就是傳說中的 HTML5 方法了,可以看下標准,代碼很簡單。IE6、7 就用老式的方法
問題十:怎麼解決伺服器間的跨域問題 服務端的解決方案的基本原理就是,由客戶端將請求發給本域伺服器,再由本域伺服器的代理來請求數據並將響應返回給客戶端。
最常用的伺服器解決方案就是利用web伺服器本身提供的proxy功能,如apache和ligd的mod_proxy模塊。在網路內 部,tran *** it的分流功能也可以解決部分跨域問題。但這些方法都有一定的局限性,鑒於安全性等問題的考慮,space這邊最後開發了一個專門用於處
理跨域請求代理服務的spproxy模塊,用於徹底解決js跨域問題。
下面我們將以空間的開放平台為例,簡單介紹下如何通過apache的mod_proxy、tran *** it的分流以及space的spproxy模塊來解
決該跨域問題,並簡單介紹下spproxy的一些特性、缺點及下一步的改進計劃。
空間在展現每個UWA開放模塊之前都必須請求該模塊的xml源代碼以進行解析,每個模塊的源代碼文件都是存放在act域下的/ow/uwa目錄下,那麼在
用戶空間首頁(hi域)中請求該xml文件時就會存在js跨域問題。要解決該問題,只能讓js向hi域的web伺服器請求xml文件,而hi域web服務
器則通過一定的代理機制(如mod_proxy、tran *** it分流、spproxy)向act域的web伺服器請求文件
F. 前端的跨域問題理解
前端真的的是亂的一筆。--來自iOS開發者的一聲哀鳴
需要把前端看成兩部分,一部分是頁面,另一部分是介面(或者加數據資源)。前端頁面中調介面是有限制的,同源策略(SOP)要求我們調用的介面必須和頁面在同一域名下,說是為了保證數據的安全。所謂同源:協議+域名+埠
但實際情況是,在前後端分離的大趨勢下,好多頁面和介面的伺服器分布在不同的域名下。比如在開發時,前端頁面分為本地環境、測試環境、模擬環境、正式環境,而介面也分為測試環境、模擬環境、正式環境,當然也可以有本地環境。他們在不同的域名下或IP下或者埠下,是不同源的。或者平時我們也能遇到需要調用不同的伺服器數據資源。顯然,同源策略保障了部分安全的同時,給開發造成了很多的麻煩。
所以,跨域問題是每個前端繞不過去的坎兒。
解決辦法有兩個方向,一個是前端解決,一個是服務端介面解除限制。
前端解決就是通過jsonp、jquery ajax、axios配置代理等。還有個簡單的,比如Mac用戶,可以使用Charles工具設置代理,臨時使用。
服務端解決可以通過nginx反向代理設置允許跨域請求的域名、或者設置Access-Control-Allow-Origin,允許跨域資源共享等。
具體解決方案可參考 https://segmentfault.com/a/1190000011145364
反觀iOS,輪廓簡直不要太清晰,大部分時候只用專注於開發,沒有各種亂七八糟的事情。