是由於瀏覽器的同源策略是對ajax請求進行阻攔了,可是不是全部的請求都給作跨域,像是通常的href屬性,a標籤什麼的都不攔截。css
如:html
項目一: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.pyjquery
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.pyajax
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)
出現了一個錯誤,這是由於同源策略給限制了,這是遊覽器給咱們報的一個錯json
(可是注意,項目2中的訪問已經發生了,說明是瀏覽器對非同源請求返回的結果作了攔截。)flask
注意:a標籤,form,img標籤,引用cdn的css等也屬於跨域(跨不一樣的域拿過來文件來使用),不是全部的請求都給作跨域,(爲何要進行跨域呢?由於我想用人家的數據,因此得去別人的url中去拿,藉助script標籤)跨域
只有發ajax的時候給攔截了,因此要解決的問題只是針對ajax請求可以實現跨域請求瀏覽器
解決同源策源的兩個方法:app
一、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的含義。
項目一:
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)