日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2021-01-14

發布時間:2024/9/30 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2021-01-14 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

背景:

同域:域名(父域名和子域名都相同),端口,協議都相同

跨域:非同域的請求

?

問題:

瀏覽器上,我們訪問127.0.0.1:80,但是127.0.0.1:80 會去請求127.0.0.1:81的數據(比如js文件,ajax請求等),此時80訪問81會出現跨域問題,但我們瀏覽器能直接訪問81的數據

?

注意:

跨域不是請求發不出去,而是服務端正常返回結果后被瀏覽器攔截返回結果。(瀏覽器為了防止非同源的請求 拿到服務器的返回數據結果)

?

解決辦法:

跨域有2種請求,瀏覽器對于2種請求的處理不一樣

簡單請求:

請求方法只能是:HEAD,GET,POST

主動設置的頭信息不能超過以下字段:Accept,Accept-Language,Content-Language,Last-Event-ID,Content-Type(只限于三個值application/x-www-form-urlencoded、multipart/form-data、text/plain)

注意:這里的頭信息是指我們主動設置的頭部信息,在查看請求過程時會發現 瀏覽器會在頭信息里設置Origin等信息,這些不算主動設置的。

非簡單請求:不能同時滿足簡單請求的2個條件

?

?

簡單請求:

瀏覽器會在 請求頭信息 里增加一個Origin字段,表明本次請求的來源,若服務器返回的頭部信息里需包含?Access-Control-Allow-Origin并包含Origin?則瀏覽器正常返回數據,否則出現跨域錯誤。

如果需要攜帶cookie,請求時需設置(比如XMLHttpRequest.withCredentials = true)。若返回頭部信息有?Access-Control-Allow-Credentials:true,則瀏覽器會正常返回數據,否則瀏覽器會攔截結果報 跨域錯誤。

注意:服務器會正常返回數據,只是瀏覽器攔截了結果。

服務器在返回頭信息里設置必須):

Access-Control-Allow-Origin: Origin? ? ? ?

Eg:Access-Control-Allow-Origin:127.0.0.1:80

如果想設置匹配所有的Origin且不帶cookie的,可以設置:

Access-Control-Allow-Origin: *

如果需要帶Cookie,需設置:

Access-Control-Allow-Credentials:true

如果想匹配所有的Origin且帶cookie:

Access-Control-Allow-Credentials: true

Access-Control-Allow-Origin: 請求的Origin(從request獲取后填入)

千萬不能同時設置Credentials=true且Origin=*,瀏覽器會報錯:

has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute

例如服務器nginx配置案例:

  • add_header Access-Control-Allow-Credentials true;

  • add_header Access-Control-Allow-Origin $http_origin;

  • ?

    非簡單請求:

    常見的情況請求方法是PUT? 或者??Content-Type字段類型是application/json?或者? ?頭信息里自定義了屬性

    過程:

    此時瀏覽器將請求分成2步:預檢請求? ?+? 簡單請求

    預檢請求:真正請求前增加一次預檢(preflight)請求(請求方法是OPTIONS),瀏覽器進行校驗,如果返回狀態碼是2XX表示驗證通過

    簡單請求:預檢通過后,發送簡單請求到服務器(瀏覽器校驗Access-Control-Allow-Origin和Origin是否匹配 +??Access-Control-Allow-Credentials 和 需要攜帶Cookie 相匹配?)。

    ?

    預檢校驗:

    請求方法:OPTIONS

    Header里增加:

    Access-Control-Request-Headers(若單獨設置了header,比如 resource:tom)

    Access-Control-Request-Method:GET(例如真正的請求的請求方式是GET)

    Origin:請求的域

    ?

    瀏覽器通過和Response里的相對應的內容進行對比(例如返回PUT,DELETE,請求的是PUT,則校驗通過)

    返回的Methods默認是包括 簡單請求 里的HEAD,POST,GET請求的(所以返回的里面填入*,也只能匹配到HEAD GET POST,不能匹配PUT等)

    返回的Headers默認是包括 簡單請求 里的幾個字段

    千萬注意:返回里面設置Methods 或者 Headers為 * 不是代表匹配到任意的內容

    注:

    預檢請求返回時,服務器可以額外配置Access-Control-Max-Age:xxx(單位秒),表示在此時間內請求不再發出另一條預檢請求。

    ?

    例如服務器nginx里配置跨域(針對OPTIONS請求直接返回2XX):

  • location /file {

  • if ($request_method = 'OPTIONS') {

  • add_header Access-Control-Allow-Origin $http_origin;

  • ? ? ? ? add_header Access-Control-Allow-Methods $http_access_control_request_method;

  • ? ? ? ? add_header Access-Control-Allow-Credentials true;

  • ? ? ? ? add_header Access-Control-Allow-Headers $http_access_control_request_method;

  • ? ? ? ? add_header Access-Control-Max-Age 1728000;

  • ?return 204;

  • ? ? }


  • ?

    后記:

    同源策略是瀏覽器保護用戶的措施,防止第三方網站請求拿到返回的數據(比如cookie和請求的返回結果)。

    針對現在前后端分離,一般會在?后端/nginx?設置僅允許?前端的IP/域名?才能跨域請求拿到結果。

    ?

    ?

    ?

    nginx里完整的跨域配置:

  • ? ? server {

  • ? ? ? ? ?listen ?80 default_server;

  • ? ? ? ? ?server_name _;??

  • ?
  • add_header Access-Control-Allow-Credentials true;

  • add_header Access-Control-Allow-Origin $http_origin;

  • ?

  • ? ? ? ? ? ? ?

  • location /file {

  • if ($request_method = 'OPTIONS') {

  • add_header Access-Control-Allow-Origin $http_origin;

  • ? ? ? ? add_header Access-Control-Allow-Methods $http_access_control_request_method;

  • ? ? ? ? add_header Access-Control-Allow-Credentials true;

  • ? ? ? ? add_header Access-Control-Allow-Headers $http_access_control_request_headers;

  • ? ? ? ? add_header Access-Control-Max-Age 1728000;

  • ? return 204;

  • }? ?

  • }

  • ?
  • }


  • ?Spring里跨域配置:

  • @Configuration

  • public class CorsConfig {

  • ?
  • @Bean

  • public CorsFilter corsFilter() {

  • final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

  • final CorsConfiguration config = new CorsConfiguration();

  • config.setAllowCredentials(true); //支持cookie 跨域

  • config.setAllowedOrigins(Arrays.asList("*"));

  • config.setAllowedHeaders(Arrays.asList("*"));

  • config.setAllowedMethods(Arrays.asList("*"));

  • config.setMaxAge(300L);//設置時間有效

  • ?
  • source.registerCorsConfiguration("/**", config);

  • return new CorsFilter(source);

  • }

  • }

  • ?

    注:這里設置AllowCredentials為*沒問題,是因為程序里做了處理(在CorsConfiguration類里):

    ?

    參考:http://www.ruanyifeng.com/blog/2016/04/cors.html

    前端跨域測試:https://blog.csdn.net/qq_35720307/article/details/83616682

    總結

    以上是生活随笔為你收集整理的2021-01-14的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。