Python跨域处理详解:JSONP与CORS实战指南

栗子
栗子
发布时间:2026-10-13| 5人浏览过
原创

本文详解Python后端处理浏览器跨域问题的两种主流方案。首先解析JSONP基于script标签的原理及GET请求限制,提供前后端完整代码示例;其次介绍通过响应头添加CORS参数及使用Django-cors-headers库的配置方法,支持所有HTTP请求类型,帮助开发者快速解决跨域报错。

跨域概念与同源策略基础

受限于浏览器的同源策略,不同源的脚本无法访问其他源下的资源。这种跨源访问即为广义上的跨域;而代码中向非同源域名发送HTTP请求则属于狭义跨域。

同源策略(SOP,Same Origin Policy)是浏览器最核心的安全机制。若缺失该策略,浏览器极易遭受XSS(跨站脚本攻击)和CSRF(跨站请求伪造)等安全威胁。

判断是否同源需检查协议、域名和端口号。若不确定,可在浏览器控制台输入window.location.origin查看返回值。

以下两种场景不受跨域限制,严格来说属于跨站资源请求:

1)页面中的链接跳转、重定向及表单提交不受同源策略限制。

2)跨域资源的引入,例如通过<script src="">、<image src="">或<iframe>等方式加载资源。

由上述第二种情况可知,通过src属性获取非同源资源时不受限制。基于此,我们可以思考是否利用这种跨站资源请求方式来实现HTTP跨域请求,即接下来要介绍的JSONP方案。

JSONP跨域方案原理与实现

1、JSONP(适用于所有GET请求,不仅限于Python)

1)实现原理:

既然Web页面请求跨站资源不受同源策略限制,我们可以尝试在服务器上生成包含所需数据的JS文件,并让Web端直接访问该JS文件以获取数据。鉴于JSON格式被JS原生支持,Web端即可通过访问动态生成的JS文件来获取跨域数据。

为便于客户端使用数据,逐渐形成了一种非正式传输协议:JSONP。其核心机制是向服务器传递一个callback参数,服务器返回数据时,将该callback参数作为函数名包裹JSON数据。

2)JSONP实例

在远程服务器新建remote.js文件:

HandleRemote({"title":"哈哈", "name":"我是一个测试数据哦!"})

在本地新建HTML文件:


function HandleRemote(data){
console.log(data.title+data.name);
}
<script type="text/javascript" src="远程服务器地址/remote.js">

运行本地文件后,在浏览器控制台可看到输出:哈哈我是一个测试数据哦!

至此实现了从服务器获取数据,还需解决两个问题:

a、如何告知远程服务器本地回调函数的名称?

b、如何在远程服务器上动态生成JS脚本?

思路明确后,先解决第一个问题:

如何让服务器知晓本地回调函数名?只需在请求中附带函数名,远程服务器根据该参数动态生成调用JS脚本即可!

前端实现


var url = "http://test.com/getRemoteDate?callback=HandleRemote"
var script = document.createElement("script");
script.setAttribute("src", url)
document.getElementByTagName("head")[0].appendChild(script);

最后将上述代码封装为通用的Ajax形式:


url = "http://test.com/getRemoteDate/";
$.ajax({
url:url,
type:"GET",
dataType:"JSONP",
jsonp:"callback", #将会作为参数传给服务器,用于获得回调函数的参数名
jsonCallback:"test", # 自定义的jsonp的回调函数参数名,默认为jQuery自动生成的函数名,也可以自定义,jQuery会自动为你处理的。
success:function(data){
此处data即为返回的json数据了,前端根据需要自行处理
} 
});

服务端代码:


def getData():
return {"title":"哈哈", "name":"这又是一个测试数据哦!"}
def getRemote(request):
funcName = request.GET.get("callback")
result = getData()
# 将结果以json形式返回,与前端的jsonp交互
return funcName+"("+json.dumps(result)+")"

配置URL:

url(r"^getRemoteData/$", getRemote)

JSONP至此完成。虽然JSONP不受同源策略限制,但其仅支持GET请求,不支持其他类型请求。

CORS响应头与Django配置

2、在响应头中添加允许跨域的参数,告知浏览器服务器接受当前请求,此方式通用性强。

3、Python Django中最常用的另一种跨域处理方式:

使用Django提供的Django-cors-headers库处理跨域。

从GitHub下载Django-cors-headers。

pip install Django-cors-headers.zip

在settings.py的中间件中配置【'corsheaders.middleware.CorsMiddleware',】,务必将其置于CSRF中间件之前,通常建议放在最前面。

设置CORS_ORIGIN_ALLOW_ALL = True以允许所有跨域请求;也可设为False,并配合CORS_ORIGIN_WHITELIST白名单使用。

如此,跨域处理即告完成,且支持所有HTTP请求类型。

补充知识:Python WSGI解决跨域问题


import json
from wsgiref.simple_server import make_server

# application()函数是Python中符合WSGI标准的一个HTTP处理函数,返回是一个字符串
def application(environ, start_response):
 # start_response 如下调用就会发送HTTP响应的Header,注意只能调用一次start_response()函数发送Header。
 # start_response 函数两个参数,一是HTTP响应码,一是一组list表示的HTTP Header,每个Header用一个包含两个str的数组表示
 status = '200 OK'
 # response_headers 中添加请求头部 ,解决跨域问题 
 response_headers = [('Content-type', 'application/json'),
   ('Access-Control-Allow-Origin', '*'),
   ('Access-Control-Allow-Methods', 'POST'),
   ('Access-Control-Allow-Headers', 'x-requested-with,content-type'),
   ] # json 
 start_response(status, response_headers)
 result = {'code': 200, 'message': "You get the flag"}
 return [result.encode()]
 
if __name__ == "__main__":
 port = 8091
 httpd = make_server("127.0.0.1", port, application)
 print("serving http on port {0}...".format(str(port)))
 httpd.serve_forever()

以上关于Python跨域处理方式的详解内容,希望能为大家提供参考,感谢支持。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。