【发布时间】:2013-03-05 23:22:08
【问题描述】:
最初,我尝试将 ajax 请求从客户端发布到第三方 url,但浏览器似乎存在安全问题。我想过向服务器端发送一个ajax,从那里向第三方发送一个GET请求,获取响应并将其发送回客户端。我怎样才能用烧瓶做到这一点?
【问题讨论】:
最初,我尝试将 ajax 请求从客户端发布到第三方 url,但浏览器似乎存在安全问题。我想过向服务器端发送一个ajax,从那里向第三方发送一个GET请求,获取响应并将其发送回客户端。我怎样才能用烧瓶做到这一点?
【问题讨论】:
正如其他答案所述,使用 Python 的 requests 模块将是从编码角度解决此问题的最佳方法。然而,正如 cmets 提到的(以及我提出这个问题的原因),这可能会导致请求被拒绝的错误。这个错误很可能是由 SELinux 引起的。
要检查这是否是问题,首先确保使用以下命令启用 SELinux:
sestatus
如果“当前模式”为“强制”,则启用 SELinux。
接下来使用此命令获取直接应用于 apache 的当前 bool 值:
getsebool -a | grep httpd
查找设置“httpd_can_network_connect”,这决定了是否允许 apache 向网络发出 TCP 请求。如果它打开,则将允许所有 apache TCP 请求。要打开它,请以 root 身份运行以下命令:
setsebool -P httpd_can_network_connect 1
如果您只需要访问数据库(我之前遇到过这个问题,这就是我在这里怀疑 SELinux 的原因),那么最好只打开“httpd_cna_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'],
)
但是,这不会达到您对客户端请求所期望的完全相同的结果。由于您的服务器无法“看到”客户端浏览器为目标站点存储的任何 cookie,因此您的代理请求将实际上是匿名的,因此,根据目标站点,可能会失败或给您与请求不同的响应浏览器中的那个资源。
如果您与第三方 URL 有关系(也就是说,如果您控制它或能够与这样做的人合作),他们可以使用 CORS 在浏览器中授予跨域请求访问权限(仅在现代浏览器中受支持)或JSON-P(一种早于 CORS 的旧解决方法)。
第三方提供商还可以让您在端点访问所需的数据,该端点旨在接受来自其他服务器的请求,并为您提供对应用进行身份验证的机制。最流行的协议是OAuth。
【讨论】:
requests.get() 是否可以工作(并再次触发路由),但即使像requests.get("localhost:5000/myroute") 这样的网址也不会导致递归调用。似乎请求不起作用......
安装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 下的目标站点。
【讨论】:
requests.get('http://example.com') 你会得到同样的结果吗? (只是为了检查没有基于用户代理或其他东西的过滤)
requests.get("http://www.google.com"),我会遇到同样的错误。我似乎找不到合适的解决方法。 @乔恩克莱门茨