1.跨域问题:
是因为浏览器的同源策略是对ajax请求进行阻拦了,但是不是所有的请求都给做跨域,像是一般的href属性,a标签什么的都不拦截。
如:
项目一:p1.html
<body> <h1>项目一</h1> <button class="send_jsonp">jsonp</button> <script> $(".send_jsonp").click(function () { $.ajax({ url:"http://127.0.0.1:8080/ajax_send2/", #去请求项目二中的url success:function (data) { console.log(data) } }) }) </script> </body>
p1.py
1 from flask import Flask 2 from flask import render_template,redirect,request,jsonify 3 app = Flask(__name__) 4 5 @app.route("/p1",methods=[\'POST\',\'GET\']) 6 def p1(): 7 return render_template(\'p1.html\') 8 9 10 if __name__ == \'__main__\': 11 app.run(host=\'127.0.0.1\',port=80)
项目二:p2.py
from flask import Flask from flask import render_template,redirect,request,jsonify app = Flask(__name__) @app.route("/ajax_send2",methods=[\'POST\',\'GET\']) def ajax_send2(): print(222222) return \'hello\' if __name__ == \'__main__\': app.run(host=\'0.0.0.0\',port=8080)
出现了一个错误,这是因为同源策略给限制了,这是游览器给我们报的一个错
(但是注意,项目2中的访问已经发生了,说明是浏览器对非同源请求返回的结果做了拦截。)
注意:a标签,form,img标签,引用cdn的css等也属于跨域(跨不同的域拿过来文件来使用),不是所有的请求都给做跨域,(为什么要进行跨域呢?因为我想用人家的数据,所以得去别人的url中去拿,借助script标签)
只有发ajax的时候给拦截了,所以要解决的问题只是针对ajax请求能够实现跨域请求
解决同源策源的两个方法:
1、jsonp(将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义。)
jsonp是json用来跨域的一个东西。原理是通过script标签的跨域特性来绕过同源策略。
借助script标签,实现跨域请求,示例:
所以只是单纯的返回一个也没有什么意义,我们需要的是数据
如下:可以返回一个字典,不过也可以返回其他的(简单的解决了跨域,利用script)
项目一:
<body> <h1>项目一</h1> <button class="send_jsonp">jsonp</button> <script> $(".send_jsonp").click(function () { $.ajax({ url:"", success:function (data) { console.log(data) } }) }); function func(arg) { console.log(arg) } </script> <script src="http://127.0.0.1:8080/ajax_send2/"></script> </body>
项目二:
def ajax_send2(request): import json print(222222) # return HttpResponse("func(\'name\')") s = {"name":"dylan","age":18} # return HttpResponse("func(\'name\')") return HttpResponse("func(\'%s\')"%json.dumps(s)) #返回一个func()字符串,正好自己的ajax里面有个func函数,就去执行func函数了,arg就是传的形参
这回访问项目一就取到值了:
这其实就是JSONP的简单实现模式,或者说是JSONP的原型:创建一个回调函数,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。
将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义。
2. jQuery对JSONP的实现:
项目一:
from flask import Flask from flask import render_template,redirect,request,jsonify app = Flask(__name__) @app.route("/p1",methods=[\'POST\',\'GET\']) def p1(): return render_template(\'p1.html\') if __name__ == \'__main__\': app.run(host=\'127.0.0.1\',port=80)
p1.html:
<body> <h1>项目一</h1> <button class="send_jsonp">jsonp</button> <script src="/static/jquery.min.js"></script> <script> $(".send_jsonp").click(function () { $.ajax({ url:"http://127.0.0.1:8080/ajax_send2", //去请求项目二中的url dataType:"jsonp", jsonp:\'callbacks\', success:function (data) { console.log(data) } }) }); </script> {#<script src="http://127.0.0.1:8080/ajax_send2"></script>#} </body>
jsonp: \'callbacks\'就是定义一个存放回调函数的键,jsonpCallback是前端定义好的回调函数方法名\'SayHi\',server端接受callback键对应值后就可以在其中填充数据打包返回了;
jsonpCallback参数可以不定义,jquery会自动定义一个随机名发过去,那前端就得用回调函数来处理对应数据了。利用jQuery可以很方便的实现JSONP来进行跨域访问。
注意 JSONP一定是GET请求
项目二:p2.py
from flask import Flask from flask import render_template,redirect,request,jsonify app = Flask(__name__) @app.route("/ajax_send2",methods=[\'POST\',\'GET\']) def ajax_send2(): import json print(222222) # return HttpResponse("func(\'name\')") s = {"name":"dylan","age":18} # return HttpResponse("func(\'name\')") callbacks = request.values.get("callbacks") # 注意要在服务端得到回调函数名的名字 print callbacks return "%s(\'%s\')" % (callbacks, json.dumps(s)) if __name__ == \'__main__\': app.run(host=\'0.0.0.0\',port=8080)
下载代码: https://files.cnblogs.com/files/dylan-wu/jsonp.rar