首页 > 编程笔记 > JavaScript笔记
阅读:12
Ajax跨域请求的两种实现方法
为了保证用户信息的安全,防止恶意的网站窃取数据,Netscape 提出了同源策略,保护本地数据不被 JavaScript 代码获取回来的数据污染。如果非同源,在请求数据时,浏览器会在控制台中显示一个异常信息,提示拒绝访问。
同源策略是指当两个页面有相同的源时,浏览器允许第一个页面的脚本访问第二个页面里的数据。同源是指域名、协议、端口都相同。反之,向服务器发送 Ajax 请求时,由于域名不同,因此属于跨域请求。
服务器通过该响应头可以指定允许来自特定 URL 的跨域请求,其值可以设置为任意 URL 或特定 URL 等。运行下面的程序:

图 1 服务器允许跨域访问的响应头设置
JSONP 实现跨域请求的原理:动态创建 <script> 标签,然后利用 <script> 标签的 src 属性不受同源策略约束这一特点来跨域获取数据。
JSONP 实现跨域请求的步骤说明如下:
下面通过实例演示如何使用 JSONP 获取百度服务器搜索数据。
实例输入搜索词“ajax”的页面效果如下图所示:

图 2 页面效果
同源策略是指当两个页面有相同的源时,浏览器允许第一个页面的脚本访问第二个页面里的数据。同源是指域名、协议、端口都相同。反之,向服务器发送 Ajax 请求时,由于域名不同,因此属于跨域请求。
Ajax跨域请求解决办法之一
为使受信任的网站之间能够跨域访问,HTML5 提供了一个新的策略,就是设置 Access-Control-Allow-Origin 响应头。服务器通过该响应头可以指定允许来自特定 URL 的跨域请求,其值可以设置为任意 URL 或特定 URL 等。运行下面的程序:
<script> // 创建 XMLHttpRequest 对象 var xhr = new XMLHttpRequest(); // 设置异步请求类型和服务器地址 xhr.open("GET", "服务器地址", true); // 监听 Ajax 状态的变化 xhr.onreadystatechange = function () { // 请求已完成并且状态码代表成功 if (xhr.readyState == 4 && xhr.status == 200) { // 控制台输出返回数据 console.log(xhr.responseText) } } // 向服务器发送数据 xhr.send(); </script>打开开发人员工具的 Network 模块可以看到,服务器的 Access-Control-Allow-Origin 响应头设置为 *,即任意 URL,因此可以正常接收数据,如下图所示。

图 1 服务器允许跨域访问的响应头设置
Ajax跨域请求解决办法之二
JSONP(JSON with Padding)是 JSON 的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。JSONP 实现跨域请求的原理:动态创建 <script> 标签,然后利用 <script> 标签的 src 属性不受同源策略约束这一特点来跨域获取数据。
JSONP 实现跨域请求的步骤说明如下:
- 定义回调函数,用于接收返回的数据。
- 创建 <script>标签,设置其 src 属性为一个跨域的 URL,URL 中应包含上一步骤中创建的回调函数名。
- 服务器收到这个请求以后,会将 JSON 数据放在回调函数的参数位置返回。
- 作为参数的 JSON 数据被视为 JavaScript 对象,而不是字符串,因此避免了使用 JSON.parse() 的步骤。
下面通过实例演示如何使用 JSONP 获取百度服务器搜索数据。
<script> var name = 'jsonp' + Math.random().toString().replace('.', ''); // 定义回调函数名 window[name] = function(data) { // 定义回调函数,将它挂载在全局对象下 console.log(typeof data); // 输出返回数据的数据类型 console.log(data); // 输出获取的数据 }; var script = document.createElement('script'); // 创建<script>标签 var attr = document.createAttribute('src'); // 创建src属性 // 设置其src属性为一个跨域的URL,包含参数callback,其值为定义的回调函数名 attr.value = '服务器地址' + '?callback=' + name; script.setAttributeNode(attr); // 将src属性添加至<script>标签 document.body.appendChild(script); // 将<script>标签添加至页面 </script>程序中:
- 第 2 行代码声明随机的回调函数名称;
- 第 3~6 行代码定义回调函数的功能,其中参数 data 用于接收服务器数据;
- 第 7~11 行代码创建 <script> 标签并初始化其属性值;
- 第 12 行代码将新创建的 <script> 标签添加至 body 中,浏览器会从设置的服务器地址获取 JSON 数据。
实例输入搜索词“ajax”的页面效果如下图所示:

图 2 页面效果