Ⅰ javahttpclient post請求 x-forwarded-for這個可以設置成其他ip么
目前,要為另一個項目提供介面,介面是用HTTP URL實現的,最初的想法是另一個項目用內jQuery post進行容請求。
但是,很可能另一個項目是部署在別的機器上,那麼就存在跨域問題,而jquery的post請求是不允許跨域的。
這時,就只能夠用HttpClient包進行請求了,同時由於請求的URL是HTTPS的,為了避免需要證書,所以用一個類繼承DefaultHttpClient類,忽略校驗過程。
寫一個SSLClient類,繼承至HttpClient。
Ⅱ java為什麼會有跨域問題
前言
相信大家在寫前端腳本的時候經常會遇到發送數據到後台的情況,但是由於瀏覽器的限制,不同域名之間的數據是不能互相訪問的,那前端怎麼和後端如何進行數據之間的交換呢?
JavaScript由於安全性方面的考慮,不允許頁面跨域調用其他頁面的對象,那麼問題來了,什麼是跨域問題?
答:這是由於瀏覽器同源策略的限制,現在所有支持JavaScript的瀏覽器都使用了這個策略。那麼什麼是同源呢?所謂的同源是指三個方面「相同」:
域名相同
協議相同
埠相同
下面就舉幾個例子來幫助更好的理解同源策略。
URL
說明
是否允許通信
http://www.a.com/a.js
http://www.a.com/b.js 同一域名 允許
http://www.a.com/a.js
http://www.b.com/a.js 不同域名 不允許
http://www.a.com:8000/a.js
http://www.a.com/b.js 同一域名不同埠 不允許
https://www.a.com/a.js
http://www.a.com/b.js 同一域名不同協議 不允許
在JAVA中處理跨域問題,通常有以下兩種常用的解決方法。
第一種解決方法
後台代碼在被請求的Servlet中添加Header設置:
Access-Control-Allow-Origin這個Header在W3C標准里用來檢查該跨域請求是否可以被通過,如果值為*則表明當前頁面可以跨域訪問。默認的情況下是不允許的。
在前端JS中需要向Servlet發出請求,請求代碼如下所示:
第二種解決方法
通過jsonp跨域請求的方式。JSONP和JSON雖然只有一個字母的區別,但是他們完全就是兩回事,很多人很容易把他們搞混。JSON是一種數據交換的格式,而JSONP則是一種非官方跨域數據交互協議。
首先來說一下前端JS是怎麼發送請求。代碼如下所示:
這里的callbackparam和success_jsonpCallback可以理解為發送的data數據的鍵值對,可以自定義,但是callbackparam需要和後台約定好參數名稱,因為後台需要獲取到這個參數裡面的值(即success_jsonpCallback)。
下面,最重要的來了,後台怎麼樣獲取和返回數據呢。代碼如下所示:
首先需要獲取參數名為callbackparam的值,這里獲取到的值就是「success_jsonpCallback」。然後將這個值加上一對小括弧。小括弧里放入你需要返回的數據內容,比如這里我返回一個JSON對象。當然你也可以返回其他對象,比如只返回一個字元串類型數據也可以。最後前端JS返回的數據就是這樣的:
瀏覽器會自動解析為json對象,這時候你只需要在success回調函數中直接用data.status就可以了。
Ⅲ 後端允許跨域怎麼設置(後端配置允許跨域無效)
跨域的幾種方法瀏覽器出於安全方面的考慮,只允許客戶端與本域(同協議、同域名、同埠,三者缺一不可)下的介面交互。不同源的客戶端腳本在沒有明確授權的情況下,不能讀寫對方的資源,這被稱為同源策略。
而有時候,我們不得不在一個客戶端下訪問不同域中的資源,於是需要用到一些方法來避開瀏覽器的同源策略,這些方法被稱為跨域。
實現跨域有如下幾種方法:
JSONP(JSONwithPadding)是數據格式JSON的一種使用模式,可以使網頁實現跨域請求。其原理主要利用了HTML的script標簽。由於script是採用開放策略,通過設置src引入不同域下的資源,所以可以通過script實現跨域,該方法需要後端支持。jsonp跨域的實現步驟如下:
下面來做個演示,首先為演示方便,將系統的hosts做如下修改:
以上例子最終實現了由example.a.com到example.b.com的跨域。應注意的是,因為script只能發送GET請求,所以jsonp只能實現GET請求的跨域。如果希望能實現其他請求的跨域,就可以用接下來介紹的一種方法——CORS。
CORS(全稱為:Cross-OriginResouceSharing)跨域資源共享,是一種通過ajax跨域請求資源的方法。瀏覽器將CORS請求分為兩大類,簡單請求(simplerequest)和非簡單請求(not-so-simplerequest,瀏覽器對這兩種請求的處理方式不一樣。如果請求滿足以下兩個條件,則為簡單請求。
簡單請求的實現方式即當用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",實現跨域。
做個演示,假設在下有一個a.html文件,其中a.html中有一個iframe,它的src為。
用降域方法實現跨域操作簡單,但是有一些缺點。比如域名只能往下設置,不能回去,比如從example.com回到a.example.com。同時如果一個子域名被攻擊,多個被降域的域名都會被連帶攻擊,有很大的安全風險。
postMessage是一個webAPI,可以實現跨域通信。window.postMessage()被調用時,會在所有頁面腳本執行完畢後,向目標窗口派發一個MessageEvent消息。語法如下:
MessageEvent具有如下屬性:
用一個與上面降域類似的例子來做演示。同樣有兩個頁面a.html和b.html,a.html中的iframe的src指向b.html。
最終實現a.html與b.html通信效果如下:
使用postMessage方法應注意的是,如果不希望從其他網站接收message,那麼不要為message事件添加任何監聽器。如果確實希望接收其他網站的message,那麼應該始終使用origin和source屬性來驗證發件人的身份,以免被惡意的網站攻擊。
以上就是幾種常見的跨域方法,各有優劣,且各自都有一定的安全問題,在日常應用中,需要有針對性的使用,對可能的安全風險採取相應措施。
前後端聯調——跨域問題
19.7.24
前端通過http請求跨域的同時需要帶上cookie信息,前端需要設置withCredentials=true。
而後端也需要有所修改。
Access-Control-Allow-Origin欄位必須指定域名,不能為*
Access-Control-Allow-Credentials為true
後端可以通過HtttpServletRequest的Header中找到Origin。是跨域地址的host加port。
後端需要維護一個跨域URL的白名單,用Origincontains匹配白名單的URL,成功則配置response的Access-Control-Allow-Origin,指定Origin。
就實現跨域傳cookie了。
參考:
什麼是跨域、怎麼解決跨域?一個請求url的**協議、埠、域名**其中任意一個與當前頁面url不相同就是跨域
即:?(http/https)協議、(segmentfault)主域名、(www)子域名、(8080)埠
是因為瀏覽器的同源策略的限制,同源策略是一種安全策略,同源指的是域名,協議,埠相同,會阻止一個域的js腳本和另一個域的內容進行交互。防止在一個瀏覽器中的兩個頁面產生不安全、異常的行為。
當然如果不同源的話會產生一定的限制:
【1】無法讀取非同源網頁的Cookie、LocalStorage和IndexedDB
【2】無法接觸非同源網頁的DOM
【3】無法向非同源地址發送AJAX請求
document.createElement(『script』)生成一個script標簽,然後插body里而已。
JSONP的實現原理就是創建一個script標簽,再把需要請求的api地址放到src里.這個請求只能用GET方法,不可能是POST(向服務端傳送數據)。
一種非正式傳輸協議,它會允許用戶傳遞一個callback參數給服務端,然後服務端返回數據的時候會將這個callback參數作為函數名來包裹住JSON數據,然後客戶端就可以隨意的定義自己的函數來處理返回的數據了。
一般是後端在處理請求數據的時候,添加允許跨域的請求頭信息,服務端設置Access-Control-Allow-Origin就可以,如果需要攜帶cookie,前後端都需要設置
window對象有個name的屬性,在一個window下,窗口載入的頁面都是共享一個window.name。
在a.html中,怎麼把b.html頁面載入進來,獲取b.html的數據。在a.html頁面使用iframe,可以去獲取b.html的數據,然後在a.html頁面中取得iframe獲取得數據。
但是iframe想要獲取b.html中的數據,只需要給這個iframe的src設為就可以,如果a.html想要得到iframe所獲得的數據,也就是iframe的window.name的值,還要把這個iframe的src設成跟a.html頁面同一個域才可以,不然a.html訪問不到iframe里的window.name屬性。
//父窗口打開一個子窗口
??varopenWindow=window.open('','title');
//父窗口向子窗口發消息(第一個參數代表發送的內容,第二個參數代表接收消息窗口的url)
??openWindow.postMessage('Nicetomeetyou!','');
調用message事件,監聽對方發送的消息
//監聽message消息
??window.addEventListener('message',function(e){
??console.log(e.source);//e.source發送消息的窗口
??console.log(e.origin);//e.origin消息發向的網址
??console.log(e.data);?//e.data?發送的消息
??},false);
??server{
??#監聽9099埠
??listen9099;
??#域名是localhost
??server_namelocalhost;
??#凡是localhost:9099/api這個樣子的,都轉發到真正的服務端地址
??location^~/api{
????proxy_pass;
??}??
?}
//請求的時候直接用回前端這邊的域名,這就不會跨域,然後Nginx監聽到凡是localhost:9099/api這個樣子的,都轉發到真正的服務端地址
fetch('',{
?method:'POST',
?headers:{
??'Accept':'application/json',
??'Content-Type':'application/json'
?},
?body:JSON.stringify({
??msg:'helloIframePost'
?})
})
關於跨域的問題一、在前端開發過程中,如果准備開發富應用,跨域的問題將會隨之而來。
????????我們先看看什麼是跨域呢:
????????所謂跨域,或者異源,是指主機名(域名)、協議、埠號只要有其一不同,就為不同的域(或源)。出於保護用戶數據的目的,瀏覽器有一個最基本的策略就是同源策略,只允許頁面內的腳本訪問當前域的資源(載入腳本、資源等不受此限制)。
二、如果瀏覽器廠商不對跨域請求進行處理,會給我們帶來什麼危害呢?
????有心人士(病毒製造者)會利用這個漏洞進行如下攻擊:
????1.CSRF/XSRF攻擊,簡單的來講就是在b.com頁面中請求a.com的介面(瀏覽器會自動帶上用戶在a.com的cookie),從而獲取用戶的在a.com的相關信息。
????2.XSS注入攻擊,類似於SQL攻擊,提交含有惡意腳本的數據到伺服器,從而達到破壞頁面或者獲取用戶的cookie。
三、我們了解到了什麼是跨域,那我們又應該如何解決呢,現在找到了這些比較權威的文章,大家先品讀一下:
????????1.mozilla官方網站關於跨域的文章(CrossOrigin),HTTP訪問控制(CORS)
????????2.mozilla官方網站關於瀏覽器同源策略的簡要介紹(SameOrigin),?瀏覽器的同源策略
四、讀完這些文章,你打算怎麼處理跨域問題呢,我先談談自己關於跨域的解決方案:
????????1.採用CORS協議,直接在Nginx中設置允許跨域的header(也可以在後端的應用程序內設置,不過在Nginx入口配置的話更加統一),在location配置中直接使用指令add_header(官方文檔鏈接),示例配置如下:
????????2.使用JSONP,也是需要後端配合,利用「瀏覽器載入腳本、資源時不受同源策略的約束」這個特性,但是這種方式非常受限制,例如只能使用GET請求,不能攜帶自定義header等。
????3.其他的一些方法,例如window.name,document.domain以及HTML5中的特性window.postMessage等
五、其他參考鏈接
????1.?淺談JS跨域問題
????2.跨域資源共享CORS詳解----阮一峰
六、聲明
????現在網路上的知識非常復雜,有些是摘自權威書籍的,有些是作者自己理解然後記錄下來的,有些是瞎掰的,所以一定要結合情況多多甄別,對於有權威文檔的知識點,建議先參考文檔。
後端配置跨域原文連接:原文地址
跨域的詳細介紹可以參考:瀏覽器和伺服器實現跨域(CORS)判定的原理,這里不多贅述。
1、主要就是客戶端向發送了服務端請求,伺服器已經能返回數據,但是瀏覽器不接收
2、在介面裡面加上:(因為request是處理請求,response是返回結果)
response.setHeader("Access-Control-Allow-Origin",?"*");
response.setHeader("Cache-Control","no-cache");?
3、如果是使用SpringBoot創建的項目,直接添加一句註解到controller和方法就可以了:
@CrossOrigin
其中@CrossOrigin中的2個參數:
origins?:允許可訪問的域列表
maxAge:准備響應前的緩存持續的最大時間(以秒為單位)。
在這個例子中,對於retrieve()和remove()處理方法都啟用了跨域支持,還可以看到如何使用@CrossOrigin屬性定製CORS配置。如果同時使用controller和方法級別的CORS配置,Spring將合並兩個注釋屬性以創建合並的CORS配置。
4、如果您正在使用SpringSecurity,請確保在Spring安全級別啟用CORS,並允許它利用SpringMVC級別定義的配置。
二、全局CORS配置
除了細粒度、基於注釋的配置之外,您還可能需要定義一些全局CORS配置。這類似於使用篩選器,但可以聲明為SpringMVC並結合細粒度@CrossOrigin配置。默認情況下,所有originsandGET,HEADandPOSTmethods是允許的。
JavaConfig
使整個應用程序的CORS簡化為:
更多使用請看原文連接和官方文檔
後端解決前端跨域請求問題場景:前後端分離,頁面和後端項目部署在不同伺服器,出現請求跨域問題。
原因: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請求。
packagecom.biz.eisp.sci.util;
importorg.apache.commons.httpclient.HttpStatus;
importjavax.servlet.*;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importjava.io.IOException;
/**
*解決跨域問題
*?
*/
{//filter介面的自定義實現
??publicvoidinit(FilterConfigfilterConfig)throwsServletException{
}
@Override
??publicvoiddoFilter(ServletRequestservletRequest,,FilterChainfilterChain)throwsIOException,ServletException{
HttpServletResponseresponse=(HttpServletResponse)servletResponse;
????HttpServletRequestrequest=(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
??publicvoiddestroy(){
}
}
2、修改web.xml文件
filter
?filter-namecors/filter-name
?filter-classcom.biz.eisp.sci.util.CorsFilter/filter-class
/filter
filter-mapping
filter-namecors/filter-name
?url-pattern/*?/url-pattern
/filter-mapping
3、spring-mvc.xml添加HttpRequestHandlerAdapter?http請求處理器適配器。
HttpRequestHandlerAdapter作為HTTP請求處理器適配器僅僅支持對HTTP請求處理器的適配。它簡單的將HTTP請求對象和響應對象傳遞給HTTP請求處理器的實現,它並不需要返回值。它主要應用在基於HTTP的遠程調用的實現上。
beanclass="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/