跨域的幾種實現方式(JSONP,Proxy,CORS)


介紹

瀏覽器安全不允許不同域名的網頁之間發送請求。這種限制叫做瀏覽器同源策略(the same-origin policy)。
實現跨域請求有以下方法:JSONP,Proxy,CORS,Nginx,Socket...

JSONP:

JSONP實現原理:利用script標簽不受同源策略限制,在頁面動態添加script,script標簽的src屬性設成api地址,並將回調函數名以get方式告訴后端,后端將數據以參數的形式返回
JSONP的優缺點:只能發get請求、不安全、老式瀏覽器支持性好

Proxy:

通過代理服務器轉發請求,實現跨域

CORS

老版瀏覽器不支持、支持所有謂詞請求,推薦使用

帶策略的CORS 和中間件

CORS中間件處理跨域請求。下面的代碼允許指定的源能對整個應用進行跨域請求

案例:

CORS中間件處理跨域請求。下面的代碼允許指定的源能對整個應用進行跨域請求
這個代碼會把CORS策略通過CORS中間件應用到這個應用的所有終端(endpoints);即把跨域作用到整個應用

指定域名可以跨域請求:

public void ConfigureServices(IServiceCollection services)
        {
         
                string[] origins = new string[] { "http://*.fan.com", "https://*.fan.com", "http://*.fan.net", "https://*.fan.net" };
                services.AddCors(option => option.AddPolicy("cors", policy => policy
                    .AllowAnyHeader()//允許所有的請求頭
                                     //.WithHeaders(HeaderNames.ContentType, "x-custom-header");//要允許一個CORS請求中指定的請求頭,可以使用 WithHeaders 來指定
                    .AllowAnyMethod()//允許所有Method
                    .SetIsOriginAllowedToAllowWildcardSubdomains()//使可以匹配一個配置的帶通配符的域名
                    .WithOrigins(origins) //指定來源域名
                    .AllowCredentials() //允許瀏覽器在跨域請求中發送證書
                ));
         }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime applicationLifetime, ILogger<Startup> logger , ElasticSearch elasticSearch)
        {
            app.UseCors("cors");//注意:1.UseCors必須在UseMvc之前被調用;2. URL末尾不能加/ ;這個url指的是 builder.WithOrigins(url)中的url
            }

不做限制,允許所有域名跨域請求:

services.AddCors(option => option.AddPolicy("cors", policy => policy
                        .AllowAnyHeader()
                        .AllowAnyMethod()
                        .SetIsOriginAllowed(_ => true) //不做任何限制
                        .AllowCredentials()
                    )
                );

使用[EnableCors]屬性設置允許跨域

[EnableCors]屬性提供了另一種方式設置跨域。即可以只設置選擇的終端,而不是所有的終端.
這里不同於上面的那種方式,上面的方式是應用的所有終端都會被設置允許跨域;
使用[EnableCors]來指定默認的策略,而[EnableCors("{Policy String}")] 指定了特定的策略;
[DisableCors]屬性可以禁止CORS;

    [EnableCors("AnotherPolicy")]
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new string[] { "green widget", "red widget" };
    }

CORS 策略(Policy)的選項:

  • 設置允許的訪問源
  • 設置允許的HTTP methods
  • 設置允許的請求頭(request header)
  • 設置暴露的響應頭(response header)
  • 跨不同源請求的證書(Credentials)
  • 設置過期時間

SetIsOriginAllowedToAllowWildcardSubdomains:設置策略的 IsOriginAllowed 屬性,使可以匹配一個配置的帶通配符的域名
AllowAnyMethod:設置允許的HTTP methods
WithHeaders:要允許一個CORS請求中指定的請求頭,可以使用 WithHeaders 來指定
AllowAnyHeader:允許所有的請求頭
withCredentials:允許在跨域請求中發送證書
WithExposedHeaders:暴露指定的響應頭

注意:如果 Access-Control-Allow-Credentials 頭部出現了,則意味着 設置為所有的源 (setting origin to " * ")會失效。

.NET Framework中實現跨域

CROS:

    /// <summary>
    /// 支持WebAPI服務器端跨域
    /// </summary>
    public class ServerCrossDomainAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            HttpRequestHeaders requestHeaders = actionExecutedContext.Request.Headers;
            if (requestHeaders.Contains("Origin"))
            {
                string originHeader = requestHeaders.GetValues("Origin").FirstOrDefault();
                if (!string.IsNullOrEmpty(originHeader))
                {
                    HttpResponseHeaders responseHeaders = actionExecutedContext.Response.Headers;
                    responseHeaders.Add("Access-Control-Allow-Origin", originHeader);
                    responseHeaders.Add("Access-Control-Allow-Credentials", "true");
                    actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
                    actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
                }
            }
        }
    }

JSONP:

    /// <summary>
    /// 支持WebAPI客戶端跨域,jsonp
    /// </summary>
    public class JSONPAttribute : ActionFilterAttribute
    {
        private const string CALL_BACK_QUERY_PARAMETER = "callback";

        public override void OnActionExecuted(HttpActionExecutedContext context)
        {
            string callback;
            if (IsJsonp(out callback))
            {
                var jsonBuilder = new StringBuilder(callback);
                jsonBuilder.AppendFormat("({0})", context.Response.Content.ReadAsStringAsync().Result);
                context.Response.Content = new StringContent(jsonBuilder.ToString());
            }
            base.OnActionExecuted(context);
        }


        private bool IsJsonp(out string callback)
        {
            callback = HttpContext.Current.Request.QueryString[CALL_BACK_QUERY_PARAMETER];
            return !string.IsNullOrEmpty(callback);
        }
    }

參考:
https://www.cnblogs.com/Vincent-yuan/p/10801513.html
https://docs.microsoft.com/zh-cn/aspnet/core/security/cors


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM