• 相关文章
    建站教程
    当前位置:启肯科技> 新闻资讯> 建站教程> 详情页

    js跨越自定义header实现跨域访问

    TAG: js跨越(1) js文件(1) 时间:2018-08-02 浏览:0

    受浏览器的同源策略限制,JavaSript只能请求本域内的资源。跨域资源共享(Cross-Origin Resource Sharing, CORS)是为解决Ajax技术难实现跨域问题而
    提出的一个规范,这个规范试着从根本上解决安全的跨域资源共享问题。在此之前,解决此类问题的途径往往是服务器代理、JSONP等,治标不治本。目
    前基本所有浏览器都已经支持该规范。
    一个域是由schema、host、port三者共同组成,与路径无关。所谓跨域,是指在http://example-foo.com/域上通过XMLHttpRequest对象调用http://example-
    bar.com/域上的资源。CORS约定服务器端和浏览器在HTTP协议之上,通过一些额外HTTP头部信息,进行跨域资源共享的协商。服务器端和浏览器都必
    需遵循规范中的要求。
    CORS把HTTP请求分成两类,不同类别按不同的策略进行跨域资源共享协商。
    1. 简单跨域请求。
    当HTTP请求出现以下两种情况时,浏览器认为是简单跨域请求:
    1). 请求方法是GET、HEAD或者POST,并且当请求方法是POST时,Content-Type必须是application/x-www-form-urlencoded, multipart/form-data或着tex
    t/plain中的一个值。
    2). 请求中没有自定义HTTP头部。
    对于简单跨域请求,浏览器要做的就是在HTTP请求中添加Origin Header,将JavaScript脚本所在域填充进去,向其他域的服务器请求资源。服务器端收
    到一个简单跨域请求后,根据资源权限配置,在响应头中添加Access-Control-Allow-Origin Header。浏览器收到响应后,查看Access-Control-Allow-Origin
    Header,如果当前域已经得到授权,则将结果返回给JavaScript。否则浏览器忽略此次响应。
    2. 带预检(Preflighted)的跨域请求。
    当HTTP请求出现以下两种情况时,浏览器认为是带预检(Preflighted)的跨域请求:
    1). 除GET、HEAD和POST(only with application/x-www-form-urlencoded, multipart/form-data, text/plain Content-Type)以外的其他HTTP方法。
    2). 请求中出现自定义HTTP头部。
    带预检(Preflighted)的跨域请求需要浏览器在发送真实HTTP请求之前先发送一个OPTIONS的预检请求,检测服务器端是否支持真实请求进行跨域资源访
    问,真实请求的信息在OPTIONS请求中通过Access-Control-Request-Method Header和Access-Control-Request-Headers Header描述,此外与简单跨域
    请求一样,浏览器也会添加Origin Header。服务器端接到预检请求后,根据资源权限配置,在响应头中放入Access-Control-Allow-Origin Header、Access-
    Control-Allow-Methods和Access-Control-Allow-Headers Header,分别表示允许跨域资源请求的域、请求方法和请求头。此外,服务器端还可以加入Acce
    ss-Control-Max-Age Header,允许浏览器在指定时间内,无需再发送预检请求进行协商,直接用本次协商结果即可。浏览器根据OPTIONS请求返回的结
    果来决定是否继续发送真实的请求进行跨域资源访问。这个过程对真实请求的调用者来说是透明的。
    XMLHttpRequest支持通过withCredentials属性实现在跨域请求携带身份信息(Credential,例如Cookie或者HTTP认证信息)。浏览器将携带Cookie Header
    的请求发送到服务器端后,如果服务器没有响应Access-Control-Allow-Credentials Header,那么浏览器会忽略掉这次响应。
    这里讨论的HTTP请求是指由Ajax XMLHttpRequest对象发起的,所有的CORS HTTP请求头都可由浏览器填充,无需在XMLHttpRequest对象中设置。以下
    是CORS协议规定的HTTP头,用来进行浏览器发起跨域资源请求时进行协商:
    1. Origin。HTTP请求头,任何涉及CORS的请求都必需携带。
    2. Access-Control-Request-Method。HTTP请求头,在带预检(Preflighted)的跨域请求中用来表示真实请求的方法。
    3. Access-Control-Request-Headers。HTTP请求头,在带预检(Preflighted)的跨域请求中用来表示真实请求的自定义Header列表。
    4. Access-Control-Allow-Origin。HTTP响应头,指定服务器端允许进行跨域资源访问的来源域。可以用通配符*表示允许任何域的JavaScript访问资源,但
    是在响应一个携带身份信息(Credential)的HTTP请求时,Access-Control-Allow-Origin必需指定具体的域,不能用通配符。
    5. Access-Control-Allow-Methods。HTTP响应头,指定服务器允许进行跨域资源访问的请求方法列表,一般用在响应预检请求上。
    6. Access-Control-Allow-Headers。HTTP响应头,指定服务器允许进行跨域资源访问的请求头列表,一般用在响应预检请求上。
    7. Access-Control-Max-Age。HTTP响应头,用在响应预检请求上,表示本次预检响应的有效时间。在此时间内,浏览器都可以根据此次协商结果决定是否
    有必要直接发送真实请求,而无需再次发送预检请求。
    8. Access-Control-Allow-Credentials。HTTP响应头,凡是浏览器请求中携带了身份信息,而响应头中没有返回Access-Control-Allo
    w-Credentials: true的,浏览器都会忽略此次响应。
    总结:只要是带自定义header的跨域请求,在发送真实请求前都会先发送 OPTIONS请求,浏览器根据OPTIONS请求返回的结果来决定是否继
    续发送真实的请求进行跨域资源访问。所以复杂请求肯定会两次请求服务端。
    js 端的ajax请求:
    [javascript] 
    1.  $.ajax({
    2.  url: "http://test.com",
    3.  dataType: 'json',
    4.  type: 'GET',
    5.  beforeSend: function (xhr) {
    6.  xhr.setRequestHeader("Test", "testheadervalue");
    7.  },
    服务端的action
    8.  async: false,
    9.  cache: false,
    10.  //contentType: 'application/x-www-form-urlencoded',
    11.  success: function (sResponse) {
    12.  }
    13.  });
    [csharp] 
    1.  //允许跨域访问
    2.  HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
    3.  HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS,DELETE,PUT");
    4.  HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Test");
    说点什么吧
    • 全部评论(0
      还没有评论,快来抢沙发吧!