王文健的博客笔记


请多指教

AJAX——前端跨域问题与部分解决办法

ajax跨域是开发中经常遇到的问题,特别是现在越来越推崇的前后端分离的开发模式,网上对于跨域的问题分享挺多,在这做个简单总结

造成跨域的原因

通过XHR实现Ajax通信的一个主要限制,来源于跨域安全策略。默认情况下,XHR对象只能访问与包含他的页面位于同一域中的资源。这种安全策略可以预防某些恶意行为。但是,实现合理的跨域请求对某些开发也是至关重要的

同源策略

  • DOM同源策略:禁止对不同源页面DOM进行操作。
  • XmlHttpRequest同源策略:禁止使用XHR对象向不同源的服务器地址发起HTTP请求。

:只要协议域名端口有任何一个不同,都被当作是不同的域,之间的请求就是跨域操作。

跨域的解决思路

  • JSONP
  • CORS(Cross-origin resource sharing) 跨源资源共享

注:这里暂时只写两个,因为我平时用到的都是CORS,其他的方案也有很多如果有机会遇到的话再补充吧

JSONP

jsonp分为两部分:

  • 回调函数:当响应到来时执行的回调函数
  • 数据:就是响应时传到回调函数中的参数

先看代码:

//先定义一个响应后执行的回调函数
function fun(resData) { //传入回调函数的json数据resData
    console.log(resData);
};
// 写一个脚本,并且告诉后端响应后执行的回调函数名叫fun
var body = document.getElementsByTagName('body')[0];
var script = document.gerElement('script');
script.type = 'text/javasctipt';
script.src = 'http://www.wwenj.com?callback=fun';
body.appendChild(script);

JSONP是通过动态<script>元素来使用,使用是为script的src元素指定一个跨域的url,如上代码,因为JSONP是有效的js代码,所以请求成功后,就会立即执行其回调函数fun(resData),resData参数就是返回的数据对象

缺点:

  • 不安全:如果其他域不安全可能会在响应中夹带恶意代码,并没办法追究
  • 确认JSONP请求是否失败并不容易
  • 只支持get请求

CORS跨源资源共享

CORS是一个W3C的一个工作草案,定义了在必须访问跨域资源时,浏览器与服务器之间如何沟通。

这里只做简单介绍,详细学习此部分可以参照阮一峰老师的跨域资源共享 CORS 详解

浏览器将CORS请求分成两类:

  • 简单请求(simple request)
  • 非简单请求(not-so-simple request)

注:这里值说简单请求

使用:
具体来说就是在浏览器发送请求时,需要给它附加一个额外的Origin头部,其中包含请求页面的源信息(协议 、 域名 、 端口)

Origin : http://www.wwenj.com

服务器端就设置一个Access-Control-Allow-Origin头部源信息http://www.wwenj.com,如果与服务端设置不符,就知道出错了,会抛出一个错误,被XMLHttpRequestonerror回调函数捕获。注意:这种错误无法通过状态码识别,因为HTTP回应的状态码有可能是200。

Access-Control-Allow-Origin : http://www.wwenj.com

如果Access-Control-Allow-Origin设为' * '表示公共资源,任何浏览器都可以访问

服务器端其他头部信息:

Access-Control-Allow-Origin: http://www.wwenj.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8
  • Access-Control-Allow-Credentials:该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。
  • Access-Control-Expose-Headers:该字段可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。上面的例子指定,getResponseHeader('FooBar')可以返回FooBar字段的值。

如果要请求提供cookie,ssl等凭据除了在服务器端设置Access-Control-Allow-Credentials: true之外还要在浏览器端设置xhr.withCredentials = true;才行,缺一不可,浏览器之间默认情况不一样,如果不想发送凭据直接显示的设置为false即可


暂写这么多,遇到更多再写

未经允许不得转载:王文健的博客笔记 » AJAX——前端跨域问题与部分解决办法

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
Copyright & copy; 2018 @王文健. All rights reserved.

小编留言

本网站是作者学习路上的一个见证,记录和敦促我的学习生活,也希望借此结交更多前辈好友。记录作者在学习生活的点点滴滴,愿与你一同进步,共勉!

Copyright & copy; 2018 @王文健. All rights reserved.

感谢 WordPress DUX 提供的参考模板与设计,阿里云提供的优质云服务,使我完成本网站的制作