我的本地网络中有一台设备,带有一个小服务器和一个REST API。我无法更改此服务器上的代码(它是商业IOT设备)。现在我正在使用Flask(Python)和JavaScript编写Web服务器。当我尝试通过JavaScript(jQuery)向此API发送HTTP请求时,我收到此错误:
Origin http://localhost is not allowed by Access-Control-Allow-Origin.
我怀疑我收到此错误,因为IOT设备Web服务器可能不包含"Access-Control-Allow-Origin", "*"
。那是对的吗?
奇怪的是,当我使用urllib2.urlopen(<server endpoint url>).read()
发送带有urllib2
的请求时,它可以工作,我从服务器获得JSON响应。 urllib2.urlopen('http://192.168.0.99/api/status').read()
get请求与jQuery get请求的不同之处是什么?为什么服务器也不阻止Python请求,因为它不允许使用localhost源的请求?
编辑:
好的,这让我的设置更加混乱:
Flask Python脚本此Flask Python脚本用于创建Web服务器以及对IOT设备进行API调用。 API调用的代码是:var request = $.ajax({
url: "http://192.168.0.99/api/status",
method: "GET"
});
request.done(function(msg) {
console.log(msg);
});
request.fail(function(jqXHR, msg) {
console.log( "Request failed: " + msg );
});
,此请求正常工作并返回JSON响应。
Flask Web服务器在烧瓶网络服务器上运行一个名为website.html的网站。在这个文件中,我想使用JavaScript对IOT设备进行API调用。我这样做的代码是:
Origin http://localhost is not allowed by Access-Control-Allow-Origin.
当我运行此代码时,我在浏览器的控制台中收到错误消息:http://localhost
。
物联网设备物联网设备通过wifi连接到路由器,并托管运行的网络服务器:http://192.168.0.99
现在问题是:为什么Python请求有效但JavaScript请求不起作用?难道他们都没有notify
作为起源吗?
答案 0 :(得分:1)
为什么服务器也不阻止Python请求,因为它不允许使用localhost源的请求?
服务器未阻止JavaScript请求;您的浏览器是。这是一些relevant information from MDN:
出于安全原因,浏览器会限制从脚本中发起的跨源HTTP请求。例如,
XMLHttpRequest
和Fetch遵循same-origin policy。因此,使用XMLHttpRequest
或Fetch 的网络应用程序只能向自己的域发出HTTP请求。为了改进Web应用程序,开发人员要求浏览器供应商允许跨域请求。
如果您无法修改服务器发送的标头,则必须解决此问题。
一种选择是设置充当IoT设备网关的本地服务。例如,由于您的Flask应用程序可以访问IoT设备,您可以向Flask应用程序发送XMLHttpRequest
并让它查询目标设备。在这种情况下,只要发送Access-Control-Allow-Origin: *
标题,Flask应用程序就可以在与浏览器相同的计算机上运行,也可以在不同的计算机上运行。