如何实现 Ajax 的跨域访问?

本文详细介绍了如何实现Ajax的跨域访问,包括同源策略、JSONP和CORS的工作原理及应用场景。CORS是现代浏览器跨域通信的标准,而JSONP适用于简单跨域场景,但只能发送GET请求。文章提供了丰富的示例代码,帮助理解两种方法的使用。
摘要由CSDN通过智能技术生成

简介

由于受浏览器的同源策略(same-origin policy)的影响, Ajax 请求默认只能在同一域名下进行访问。

同源策略是浏览器安全的基石,所有的浏览器都实行了这个策略。

同源策略

同源策略是指三个相同:

  • 协议相同(比如,都是 http)
  • 域名相同(比如,都是 www.example.com
  • 端口相同(比如,都是 80 端口)

同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取用户的数据。

如果非同源,共有三种行为受到限制:

  • Cookie、LocalStorage 和 IndexDB 无法读取
  • DOM 无法获得
  • AJAX 请求不能发送

下面,我们只讲述 AJAX 请求如何规避同源策略的影响。

Ajax 的跨域场景描述

这里,我先描述一下 Ajax 的跨域场景。

在网站 http://apidemo.test ,有一个 API 接口,http://apidemo.test/api/test 。 它的路由为:

Route::get('test', function(){
    return response()->json(['id'=>1, 'name'=>'test']);
});

在本网站的某个页面,也就是同源的情况下,执行的 Ajax 请求为:

$.get('http://apidemo.test/api/test', function(data){ console.log(data) });

可以得到正确的 json 响应:

{
   id: 1, name: "test"}

但是,现在如果要从另外一个网站(http://adm.test)的某个页面( http://adm.test/demo ),发送 Ajax 请求到 http://apidemo.test/api/test

$.get('http://apidemo.test/api/test', function(data){ console.log(data) });

就属于 Ajax 的跨域问题,由于不同源,所以会报错:

Failed to load http://apidemo.test/api/test: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://adm.test' is therefore not allowed access.

实现 Ajax 的跨域访问

同源政策规定,AJAX 请求只能发给同源的网址,否则就报错。

除了架设服务器代理(浏览器请求同源服务器,再由后者请求外部服务),还有三种方法规避这个限制。

  • WebSocket
  • JSONP
  • CORS

WebSocket

WebSocket 是一种通信协议,使用 ws://(非加密)和 wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持 WebSocket ,就可以通过它进行跨源通信。

由于 WebSocket 很少用到,故这里不作讲述。感兴趣的可自行参考:http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html

JSONP

JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,老式浏览器全部支持,服务器改造非常小。

JSONP (JSON with Padding)是 JSON 的一种“使用模式”,可用于解决浏览器的跨域数据访问的问题。

JSONP 的基本思想是:

  • 服务器端返回的数据格式是一段可在客户端执行的 javascript 代码,形如:callback_name(json_data)
  • 客户端获取该 jsonp 数据,并自动执行回调函数。

这种使用模式就是所谓的 JSONP。用 JSONP 抓到的数据并不是 JSON,而是任意的 JavaScript。

首先,我们修改服务器端 http://apidemo.test/api/test 返回的数据内容:

Route::get('test', function(){
    $callback = $_REQUEST['callback'];  // 获取回调函数名
    $json_data = json_encode(['id'=>1, 'name'=>'test']);
    return $callback . "(" . $json_data . 
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值