如何从我的Flask应用发送GET请求到其他网站?
最开始,我想从我的客户端发送一个ajax请求到一个第三方的网址,但似乎浏览器对这个操作有安全限制。我想到了一个办法,就是先把ajax请求发送到我的服务器上,然后再从服务器去请求那个第三方的网址,获取到响应后再把结果发回给客户端。我该怎么用flask来实现这个呢?
3 个回答
正如其他回答所说,使用Python的requests模块是处理这个问题的最佳方法。不过,正如评论中提到的(也是我来这个问题的原因),这可能会出现请求被拒绝的错误。这个错误很可能是由于SELinux引起的。
要检查是否是这个问题,首先可以用以下命令确认SELinux是否启用:
sestatus
如果'当前模式'是'enforcing',那么SELinux就是启用的。
接下来,用以下命令获取与apache直接相关的当前布尔值:
getsebool -a | grep httpd
查找设置'httpd_can_network_connect',这个设置决定了apache是否被允许向网络发起TCP请求。如果这个设置开启了,那么所有apache的TCP请求都会被允许。要开启它,可以以root身份运行以下命令:
setsebool -P httpd_can_network_connect 1
如果你只需要数据库访问(我之前遇到过这个问题,所以我怀疑是SELinux),那么最好只开启'httpd_can_network_connect'。
这个策略的目的是,如果黑客劫持了你的apache服务器,他们就无法通过服务器访问你内部网络的其他部分。
这本来可以作为评论发出去,但我没有足够的声望。
来源: https://tag1consulting.com/blog/stop-disabling-selinux https://wiki.centos.org/TipsAndTricks/SelinuxBooleans
Flask本身并不具备这个功能,但你可以很简单地写一个请求处理程序,使用HTTP客户端库向另一个服务器发起请求,然后把那个服务器的响应返回给用户。
# third-party HTTP client library
import requests
# assume that "app" below is your flask app, and that
# "Response" is imported from flask.
@app.route("/proxy-example")
def proxy_example():
r = requests.get("http://example.com/other-endpoint")
return Response(
r.text,
status=r.status_code,
content_type=r.headers['content-type'],
)
不过,这样做的结果可能和你在浏览器中直接请求时的结果不完全一样。因为你的服务器无法“看到”客户端浏览器为目标网站存储的任何cookies,所以通过你的服务器发出的请求实际上是匿名的。因此,具体结果可能会因为目标网站的不同而失败,或者返回的内容和你在浏览器中请求时得到的不同。
如果你和那个第三方网址有关系(也就是说,你控制这个网址或者能和控制它的人合作),他们可以通过使用CORS(这只在现代浏览器中支持)来允许浏览器进行跨域请求,或者使用JSON-P(这是一种比CORS更早的解决方案)。
第三方提供者也可以给你一个专门的接口,让你可以从其他服务器请求你想要的数据,并提供一种方式让你验证你的应用。最流行的协议就是OAuth。
首先,安装 requests
模块(这个比用 urllib2
要好用多了),然后定义一个路由来发送需要的请求,像这样:
import requests
from flask import Flask
app = Flask(__name__)
@app.route('/some-url')
def get_data():
return requests.get('http://example.com').content
不过,根据你的设置,最好是配置你的网络服务器,让它在某个特定的URL下反向代理到目标网站。