我正在使用React.js创建一个天气应用程序,我想发一个CORS请求从天气地下网站获取数据。 我想要的是获取城市名称,使用自动完成API查找城市并获取该城市的数据。
问题是,每当我给出一个城市名称(例如:德黑兰)时,xhr.onerror
事件处理程序就会运行并且我收到此错误:
XMLHttpRequest cannot load http://autocomplete.wunderground.com/aq?query=tehran. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
这是我获取数据的代码:
var axios = require('axios');
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
xhr.open(method, url, true);
}
else if (typeof XDomainRequest != "undefined") {
xhr = new XDomainRequest();
xhr.open(method, url);
}
else {
xhr = null;
}
return xhr;
}
function makeCorsRequest(url) {
var autoCompleteText;
var xhr = createCORSRequest('GET', url);
if (!xhr) {
alert('CORS not supported');
return;
}
xhr.onload = function() {
var text = xhr.responseText;
autoCompleteText = text;
}
xhr.onerror = function() {
alert('Woops, there was an error making the request.');
}
xhr.send();
return autoCompleteText;
}
const WEATHER_UNDERGROUND_AUTOCOMPLETE = 'http://autocomplete.wunderground.com/aq?query=';
const WEATHER_UNDERGROUND_URL = 'http://api.wunderground.com/api/eda52d06d32d71e9/conditions/q/';
module.exports = {
getTemp: function(city) {
var encodedCity = encodeURIComponent(city);
var requestAutoComplete = `${WEATHER_UNDERGROUND_AUTOCOMPLETE}${encodedCity}`;
var autoCompleteText = makeCorsRequest(requestAutoComplete);
var foundCity = autoCompleteText.RESULTS[0].name.split(', ');
var requestUrl = `${WEATHER_UNDERGROUND_URL}${foundCity[1]}/${foundcity[0]}.json`;
return axios.get(requestUrl).then(function(res) {
return res.data.current_observation.temp_c;
}, function(err) {
throw new Error(res.data.error);
});
}
}
该应用的屏幕截图: localhost:3000/weather page
答案 0 :(得分:1)
这是一个简单的反应组件,它使用查询参数调用api并获得所需的结果。
import React, { Component } from 'react'
import axios from 'axios';
export default class App extends Component {
componentDidMount() {
axios.get('http://autocomplete.wunderground.com/aq?query=tehran')
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log(error);
})
}
render () {
return (
<div>React simple starter</div>
)
}
}
答案 1 :(得分:0)
由于http://autocomplete.wunderground.com/aq?query=tehran
未发送Access-Control-Allow-Origin
响应标头,因此您必须更改前端代码,而不是通过代理发出请求。通过更改WEATHER_UNDERGROUND_AUTOCOMPLETE
值来执行此操作:
const WEATHER_UNDERGROUND_AUTOCOMPLETE =
'https://cors-anywhere.herokuapp.com/http://autocomplete.wunderground.com/aq?query=';
https://cors-anywhere.herokuapp.com/http://autocomplete.wunderground.com/…
网址会导致请求转到https://cors-anywhere.herokuapp.com
,这是一个公共CORS代理,可将请求发送到您想要的http://autocomplete.wunderground.com…
网址。
该代理获取响应,接受并向其添加Access-Control-Allow-Origin
响应头,然后最终将其作为响应传递回您的请求前端代码。
因此,最终因为浏览器看到带有Access-Control-Allow-Origin
响应标头的响应,浏览器允许您的前端JavaScript代码访问响应。
或者使用https://github.com/Rob--W/cors-anywhere/之类的代码来设置您自己的代理。
在这种情况下您需要代理,因为http://autocomplete.wunderground.com/…
本身不会发送Access-Control-Allow-Origin
响应标头 - 在这种情况下,您的浏览器将不允许您的前端JavaScript代码访问该服务器的响应跨来源。
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS有更多详情。
顺便提一下,您可以使用curl
或其他工具验证服务器是否未发送标头:
$ curl -i -H 'Origin: http://localhost:3000' \
'http://autocomplete.wunderground.com/aq?query=tehran'
HTTP/1.1 200 OK
Content-type: application/json; charset=utf-8
Content-Length: 2232
Connection: keep-alive
{ "RESULTS": [
{
"name": "Tehran Dasht, Iran",
…
请注意,响应标头中没有Access-Control-Allow-Origin
。
答案 2 :(得分:0)
你必须使用axios吗?如果不是,我强烈推荐Mozilla的Fetch。要使用fetch进行cors api调用,请执行以下操作:
var myInit = {
method: 'GET',
mode: 'cors',
credentials: 'include'
};
fetch(YOUR_URL, myInit)
.then(function(response) {
return response.json();
})
.then(function(json) {
console.log(json)
});
您可以在此处了解详情:https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
答案 3 :(得分:0)
如果您遇到发出CORS
请求的问题,请使用此简单的chrome extension (允许控制允许来源)。
这样,您就可以CORS
进行headers/config
请求而无需在m=list(zip(*l)[-1]) # last column
if "5\n" in m:
...
中添加任何额外参数。