分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 软件开发

Ajax跨域请求

发布时间:2023-09-06 01:44责任编辑:沈小雨关键词:Ajax跨域

一、同源策略

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,

如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。

可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。

所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,

即检查是否同源,只有和百度同源的脚本才会被执行,如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。
 
在下面的实例中,通过Ajax访问自己的页面没有问题:
实例:
前端代码
后端代码

结果:

二、跨域

所谓的跨域就是请求的并不是本地url,具体实例请看:

 现在在项目1通过ajax访问项目2的页面(8001访问8002):

点击按钮发现并没有返回我们希望看到的,那到底是哪一步出现了问题了:

在项目2的后台,我们看到:

证明了已经处理了,难道是接收被拦截了,在火狐查看前端页面:

问题很明显就是被拦截了,为什么被拦截了?我只能说这是一种安全措施,这是在浏览器设计之初就已经规定好的,一直延续至今。

 

三、跨域的解决方法

在实际工作中,由于在大互联网时代,各行各业分工十分细化,单就大数据而言,

有些公司专门做数据收集、有些公司只做数据处理、而有些只做销售,这些公司传输数据的手段就是跨域请求。

下面会讲解三种解决跨域的方法:

1.借助script标签实现跨域

我们常用的Jquery可以这样:

<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>

在项目启动进行加载的时候,就会去对应的服务器取数据,利用这种特性可以实现跨域请求:

返回一个func(),这样在前端:

最后就能打印其中的数据了。

如果把需要传递的数据放在括号里面,就能把它取出来了,这样就可以达到跨域请求的目的了。

为了达到数据的丰富性,我们可以先进行序列化。

最后实现的代码详解:

前端代码:

<!DOCTYPE html><html lang="en"><head> ???<meta charset="UTF-8"> ???<meta http-equiv="X-UA-Compatible" content="IE=edge"> ???<meta name="viewport" content="width=device-width, initial-scale=1"> ???<title>Title</title> ???<script src="/static/jquery-3.2.1.min.js"></script></head><body><h3>这是项目1</h3><button class="b1">send a ajax</button>{% csrf_token %}<script> ???function func(s) { ???????console.log(s) ???} ???????function cross_domain(url) {{# ???????定义一个标签,添加一个url元素,将其添加到body里面#}{# ???????为了不每次点击都会加载一个script标签,每次加载之后就删除#} ???????var $ele_script = $("<script>"); ???????$ele_script.attr("src",url); ???????$ele_script.attr("class","cs"); ???????$("body").append($ele_script); ???????$(".cs").remove() ???}{# ???点击按钮的时候就会触发,此时才会加载<script>#}{# ???使用callback=func可以将后端传输字符串进行解耦,在后端可以接收callback,这样再传递func()到前端#} ???$(".b1").click(function () { ???????cross_domain("http://127.0.0.1:8002/ajax_send/?callback=func") ???})</script></body></html>

后端代码:

from django.shortcuts import render,HttpResponsedef index(request): ???return render(request,"index.html")import jsondef ajax_send(request): ???dict = {"name":"kebi"} ???func =request.GET.get("callback") ?#这样可以不用固定函数名 ???return ?HttpResponse("%s(%s)"%(func,json.dumps(dict)))

这其实就是JSONP的简单实现模式,或者说是JSONP的原型:创建一个回调函数,

然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。

jsonp是json用来跨域的一个东西。原理是通过script标签的跨域特性来绕过同源策略。

将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义。

一般情况下,我们希望这个script标签能够动态的调用,而不是像上面因为固定在html里面所以没等页面显示就执行了,很不灵活。

我们可以通过javascript动态的创建script标签,这样我们就可以灵活调用远程服务了。

2.jQuery对JSONP的实现

(1)getJSON

jQuery框架也当然支持JSONP,可以使用$.getJSON(url,[data],[callback])方法:

项目一前端部分:

<script> ???$(".b1").click(function () { ???????$.getJSON("http://127.0.0.1:8002/ajax_send/?callback=?",function (data) {{# ???????????callback=?这个值系统会帮你随机生成,就相当于让面的ross_domain#}{# ???????????当拿到结果之后,只会执行function ()这个匿名函数#} ???????????console.log(data) ???????}) ???})</script>

项目二后端部分:

import jsondef ajax_send(request): ???dict = {"name":"kebi"} ???func =request.GET.get("callback") ???print("func",func) ?#func jQuery3210924015436172589_1519900847362 ???print("项目2.。。") ???return ?HttpResponse("%s(%s)"%(func,json.dumps(dict)))

经过测试可以知道,这种方法也是可以的,其实就是对script的封装。

结果是一样的,要注意的是在url的后面必须添加一个callback参数,这样getJSON方法才会知道是用JSONP方式去访问服务,

callback后面的那个问号是内部自动生成的一个回调函数名。

此外,如果说我们想指定自己的回调函数名,或者说服务上规定了固定回调函数名该怎么办呢?我们可以使用$.ajax方法来实现

(2)$.ajax

看到这个有些人就疑惑,这个不就是Ajax吗,不是说ajax不行吗,这咋就又行了?

其实确实不行,只是Jquery的作者让它和ajax同名而已。

项目一前端:

<script>$(".b1").click(function () { ??$.ajax({ ??????url:‘http://127.0.0.1:8002/ajax_send/‘, ??????dataType:"jsonp", ??{# 期待数据类型,一定要加,只要有这句话,就会去添加script标签 #} ??????jsonp: ‘callback‘, ?{# 其实就是补充在后面:http://127.0.0.1:8002/ajax_send/?callback=SayHi#} ??????jsonpCallback:"SayHi" ?{# 如果这里不加jsonpCallback,就会是callback=?,这样就是getJson #} ??});});function SayHi(data) { ???console.log(data)}</script>

项目二后端:

def ajax_send(request): ???dict = {"name":"kebi"} ???func =request.GET.get("callback") ???print("func",func) ?#func SayHi ???print("项目2.。。") ???return ?HttpResponse("%s(%s)"%(func,json.dumps(dict)))

当然,最简单的形式还是通过回调函数来处理(推荐):

<script>$(".b1").click(function () { ??$.ajax({ ??????url:‘http://127.0.0.1:8002/ajax_send/‘, ??????dataType:"jsonp", ?????????jsonp: ‘callback‘, ???????success:function (data) { ??????????console.log(data) ??????} ??});});</script>

 jsonp: ‘callbacks‘就是定义一个存放回调函数的键,jsonpCallback是前端定义好的回调函数方法名‘SayHi‘,

server端接受callback键对应值后就可以在其中填充数据打包返回了; 

jsonpCallback参数可以不定义,jquery会自动定义一个随机名发过去,那前端就得用回调函数来处理对应数据了。

利用jQuery可以很方便的实现JSONP来进行跨域访问。

  

注意:JSONP一定是GET请求

最后来一个跨域请求的实例:

<input type="button" onclick="AjaxRequest()" value="跨域Ajax" /><div id="container"></div> ???<script type="text/javascript"> ???????function AjaxRequest() { ???????????$.ajax({ ???????????????url: ‘http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403‘, ???????????????type: ‘GET‘, ???????????????dataType: ‘jsonp‘, ???????????????jsonp: ‘callback‘, ???????????????jsonpCallback: ‘list‘, ???????????????success: function (data) { ???????????????????$.each(data.data,function(i){ ???{# 循环 #} ???????????????????????var item = data.data[i]; ???????????????????????var str = "<p>"+ item.week +"</p>"; ??{# 添加日期标签 #} ???????????????????????$(‘#container‘).append(str); ???????????????????????$.each(item.list,function(j){ ??{# 循环 #} ???????????????????????????var temp = "<a href=‘" + item.list[j].link +"‘>" + item.list[j].name +" </a><br/>"; ???????????????????????????$(‘#container‘).append(temp); ???????????????????????}); ???????????????????????$(‘#container‘).append("<hr/>"); ???????????????????}) ???????????????} ???????????}); ???????}</script>
跨域请求

Ajax跨域请求

原文地址:https://www.cnblogs.com/yangmingxianshen/p/8490221.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved