js ajax Django跨域,Django框架中JSONP跨域请求的本质以及解决方式

为了更好的解释JSONP跨域请求的本质,我们先通过Python的爬虫请求模块requests,来看一下有什么效果。requests模块的功能就是请求url然后返回response信息,我们还是使用Django来实现。创建req路由规则,通过requests.get向某个数据API接口发送请求,并返回response,将response.text文本展示在req的url中,具体实现:

以上代码请求的是一个iconfont图标的api接口,html是接口的数据,我们传递到req.html页面中并展示出来,其它地方自行配置好,那么我们可以看到没什么问题,数据呈现在网页中,并且浏览器的控制台也没有错误信息。

这种方式是通过requests去请求数据接口,然后放到我们的django服务端。我们试试直接通过django的服务器去获取数据,会发生什么。接下来在req.html页面搞个按钮,并绑定js事件,点击就会访问api接口:

现在运行django服务端,然后点按钮请求数据,那么就成功的触发了下图的报错信息:

3057a2e940ab1f1efc40b90e48ac7f7c.png

英文报错:No ‘Access-Control-Allow-Origin’ header is present on the requested resource.,翻译过来就是已被CORS策略阻止:请求的资源上不存在“Access Control Allow origin”头。

其实我们呢在点击按钮的时候已经成功的向数据接口发送信息,并且对方已经吧数据给我们了,但是被浏览器拒绝了,这是由于浏览器的同源策略,它不允许你向其它域名发送ajax请求。鳄鱼君Ba提供了一下三种方式来解决:

通过jsonp处理跨域(基于原生js)

注意:jsonp只能模拟get请求处理跨域

1、jsonp介绍

jsonp是json用来跨域的一个东西。原理是通过script标签的跨域特性来绕过同源策略。下面介绍一个jsonp基本实现原理,即利用script特性实现跨域请求,如下实例:

2、基于JS的JSONP的实现

一般情况下,我们希望这个script标签能够动态的调用,我们可以通过页面的触发事件操作后,通过javascript动态的创建script标签,这样我们就可以灵活调用远程服务。实例如下:

前面的两种方式进行对比,你就会发现真的是浏览器阻止了对方返回的数据。第一种是使用requests请求数据接口,返回并展示在浏览器中,浏览器只是参与了展示信息;第二种是通过ajax的xhr对象发送请求,这个过程了是借助浏览器来发送请求的,但是数据被阻止了。解决办法很简单,浏览器会阻止Ajax请求,但是不会阻止通过script标签发送的请求,这是前辈们说的,我也不知道,所以试试看:

修改代码后运行django服务端,那么又一次非常开心的看到浏览器又给了一些提示Cross-Origin Read Blocking (CORB) blocked cross-origin response https://xxx with MIME type application/json.(跨源读取阻塞(CORB)用MIME类型application/json阻塞了跨源响应https://xxx。),前面其实还有一个错误:A cookie associated with a cross-site resource at https://www.iconfont.cn/ was set without the `SameSite` attribute. A future release of Chrome will only deliver cookies with cross-site requests if they are set with `SameSite=None` and `Secure`. (与https://www.iconfont.cn/上的跨站点资源关联的cookie未设置“SameSite”属性。如果Chrome的未来版本设置为“SameSite=None”和“Secure”,则它只能传递带有跨站点请求的cookie)。

为了更加灵活,可以自己在客户端定义一个回调函数,然后将函数名传送给服务端,服务端则会返回以你定义的回调函数名的方法,将获取的json数据传入这个方法完成回调。这里你需要使用django创建两个服务端才可以。一般来说所有的网站都是这样使用的,你可以自己尝试一下。

通过jsonp处理跨域(基于jQuery中的getJSON方法)

基于jQuery框架也当然支持JSONP,可以使用$.getJSON(url,[data],[callback])方法。与js实现的方式相比,我们并不要自己生成一个script标签,客户端也并不需要自己定义一个回调函数,要注意的是在$.getJSON(url,[data],[callback])方法的url的后面必须添加一个callback参数,这样getJSON方法才会知道是用JSONP方式去访问服务,callback后面的那个问号是内部自动生成的一个回调函数名。

通过jsonp处理跨域(基于jQuery中的ajax方法)

上述这种方法,很方便,不需要我们自己定义回调函数和指定回调函数名,但是,如果说我们想指定自己的回调函数名,或者说服务上规定了固定回调函数名该怎么办呢?我们可以使用$.ajax方法来实现。如下例:

3.添加允许访问的白名单,凡是出现在白名单的域名都可以访问后端接口

CorsMiddleware应该放置得尽可能高,特别是在可以产生响应的任何中间件之前, 如Django CommonMiddleware或Whitenoise WhiteNoiseMiddleware。 如果以前没有,则无法将CORS头添加到这些响应中。

暂且先整理,鳄鱼君Ba在django中测试的时候一直没有解决cors问题,待更新…….

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值