Axios 请求雅虎天气 API 失败
Axios request to yahoo weather API failing
我正在开发一个 vuejs 组件,它使用 axios 向 Yahoo weather API 发出 ajax GET 请求。我收到一个 CORS 错误,因为预检检查没有通过访问控制检查。
但是,我可以使用 jqueries ajax 方法毫无问题地向同一端点发出请求,并且预期的数据会从服务返回。有谁知道为什么会这样?
这是我的 vue 组件的代码:
<template>
<div class="tile" id="time-weather">
<div class="date" v-text='this.date'></div>
<div class="time" v-text='this.time'></div>
<div class="temperature" v-text="this.temp"></div>
</div>
</template>
<script>
import moment from 'moment';
export default {
created() {
this.refreshTime();
setInterval(this.refreshTime, 1000);
this.fetchWeather();
},
data() {
return {
date: '',
time: '',
temp: ''
}
},
methods: {
refreshTime() {
this.date = moment().format('ddd DD/MM');
this.time = moment().format('HH:mm:ss');
},
fetchWeather() {
const endpoint = "https://query.yahooapis.com/v1/public/yql?q=select item.condition from weather.forecast where woeid in (select woeid from geo.places(1) where text='Sunderland') and u='c'&format=json";
const yapi = axios.create({
url: endpoint,
method: 'get',
withCredentials: false
});
const response = yapi.request();
console.log(response);
}
}
}
</script>
我在控制台中收到的确切错误消息是:
XMLHttpRequest cannot load
https://query.yahooapis.com/v1/public/yql?q=select%20item.condition%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text=%27Sunderland%27)%20and%20u=%27c%27&format=json.
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://dashboard.dev' is therefore not allowed
access.
正如我提到的,如果我使用 jQuery.ajax();
向同一个端点发出请求,则请求发送没有问题。
我可能遗漏了一些明显的东西,但我似乎无法解决这个问题。
任何帮助将不胜感激。
干杯!
我收到了回复,但我需要使用 https
,而不是 http
- axios 和 JQuery 都是如此。
运行 下面的代码片段或此 CodePen Demo 以查看响应:
axios.get(
"https://query.yahooapis.com/v1/public/yql?q=select item.condition from weather.forecast where woeid in (select woeid from geo.places(1) where text='Sunderland') and u='c'&format=json"
)
.then(function(result) {
console.log(result);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.12.0/axios.min.js"></script>
仅从问题的当前详细信息来看,无法确定您的浏览器为什么会出现 CORS preflight OPTIONS
request——但可以确定的是,它失败的原因是 https://query.yahooapis.com/v1/public/yql
端点未在 OPTIONS
响应中发送 Access-Control-Allow-Origin
响应 header。
您可以通过执行以下操作确认使用 curl
:
curl -X OPTIONS -i \
-H 'http://dashboard.dev/' \
'http://query.yahooapis.com/v1/public/yql?q=select%20item.condition%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text=%27Sunderland%27)%20and%20u=%27c%27&format=json'
HTTP/1.1 200 OK
Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS
Content-Length: 0
Date: Wed, 23 Aug 2017 22:12:40 GMT
Age: 0
Connection: keep-alive
Via: http/1.1 a44.ue.sg3.yahoo.net (ApacheTrafficServer [c sSf ])
Server: ATS
I am working on a vuejs component that makes an ajax GET request to the Yahoo weather API using axios. I am receiving a CORS error in that the preflight check… if I make the request using jQuery.ajax()
to the same endpoint, the request is sent with no issues.
这表明 jQuery.ajax()
没有以触发预检的方式发出请求,但 axios 请求是。几乎可以肯定,axios 请求正在添加一个或多个自定义请求 header——我猜可能是 X-Requested-With
header*——而 jQuery.ajax()
不是。
* 更新: 原来在这个例子中被添加的 header 是 X-CSRF-TOKEN
.
要确切地知道发生了什么,请检查浏览器发送的 OPTIONS
请求——特别是 OPTIONS
请求中的 Access-Control-Request-Headers
请求 header。这将包含 axios 请求试图添加到请求中的任何自定义请求的名称 header。
您可以查看 header 和 OPTIONS
请求的其他详细信息,方法是进入浏览器 devtools 中的网络窗格并重新加载,然后检查那里的 OPTIONS
请求。
无论如何,有一种方法可以使该端点的请求无论如何都按预期工作。您可以通过 CORS 代理发出请求,方法是将前端代码更改为:
const proxyurl = "https://cors-anywhere.herokuapp.com/";
const endpoint = "https://query.yahooapis.com/v1/public/yql?q=select item.condition from weather.forecast where woeid in (select woeid from geo.places(1) where text='Sunderland') and u='c'&format=json";
const yapi = axios.create({
url: proxyurl + endpoint,
method: 'get',
withCredentials: false
});
这将通过 https://cors-anywhere.herokuapp.com 发送请求——浏览器的预检 OPTIONS
请求和您的 GET
请求。那里的后端将请求转发到 https://query.yahooapis.com/v1/public/yql
端点并接收响应。
那里的后端然后将 Access-Control-Allow-Origin
header 添加到响应中——在 OPTIONS
的情况下,还有 Access-Control-Allow-Headers
和 Access-Control-Allow-Methods
响应 headers——然后将其传递回您的请求前端代码。
然后浏览器将允许您的前端代码访问响应,因为带有 Access-Control-Allow-Origin
响应 header 的响应是浏览器所看到的。
轻松设置自己的 CORS 代理
我正在开发一个 vuejs 组件,它使用 axios 向 Yahoo weather API 发出 ajax GET 请求。我收到一个 CORS 错误,因为预检检查没有通过访问控制检查。
但是,我可以使用 jqueries ajax 方法毫无问题地向同一端点发出请求,并且预期的数据会从服务返回。有谁知道为什么会这样?
这是我的 vue 组件的代码:
<template>
<div class="tile" id="time-weather">
<div class="date" v-text='this.date'></div>
<div class="time" v-text='this.time'></div>
<div class="temperature" v-text="this.temp"></div>
</div>
</template>
<script>
import moment from 'moment';
export default {
created() {
this.refreshTime();
setInterval(this.refreshTime, 1000);
this.fetchWeather();
},
data() {
return {
date: '',
time: '',
temp: ''
}
},
methods: {
refreshTime() {
this.date = moment().format('ddd DD/MM');
this.time = moment().format('HH:mm:ss');
},
fetchWeather() {
const endpoint = "https://query.yahooapis.com/v1/public/yql?q=select item.condition from weather.forecast where woeid in (select woeid from geo.places(1) where text='Sunderland') and u='c'&format=json";
const yapi = axios.create({
url: endpoint,
method: 'get',
withCredentials: false
});
const response = yapi.request();
console.log(response);
}
}
}
</script>
我在控制台中收到的确切错误消息是:
XMLHttpRequest cannot load https://query.yahooapis.com/v1/public/yql?q=select%20item.condition%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text=%27Sunderland%27)%20and%20u=%27c%27&format=json. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://dashboard.dev' is therefore not allowed access.
正如我提到的,如果我使用 jQuery.ajax();
向同一个端点发出请求,则请求发送没有问题。
我可能遗漏了一些明显的东西,但我似乎无法解决这个问题。
任何帮助将不胜感激。
干杯!
我收到了回复,但我需要使用 https
,而不是 http
- axios 和 JQuery 都是如此。
运行 下面的代码片段或此 CodePen Demo 以查看响应:
axios.get(
"https://query.yahooapis.com/v1/public/yql?q=select item.condition from weather.forecast where woeid in (select woeid from geo.places(1) where text='Sunderland') and u='c'&format=json"
)
.then(function(result) {
console.log(result);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.12.0/axios.min.js"></script>
仅从问题的当前详细信息来看,无法确定您的浏览器为什么会出现 CORS preflight OPTIONS
request——但可以确定的是,它失败的原因是 https://query.yahooapis.com/v1/public/yql
端点未在 OPTIONS
响应中发送 Access-Control-Allow-Origin
响应 header。
您可以通过执行以下操作确认使用 curl
:
curl -X OPTIONS -i \
-H 'http://dashboard.dev/' \
'http://query.yahooapis.com/v1/public/yql?q=select%20item.condition%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text=%27Sunderland%27)%20and%20u=%27c%27&format=json'
HTTP/1.1 200 OK
Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS
Content-Length: 0
Date: Wed, 23 Aug 2017 22:12:40 GMT
Age: 0
Connection: keep-alive
Via: http/1.1 a44.ue.sg3.yahoo.net (ApacheTrafficServer [c sSf ])
Server: ATS
I am working on a vuejs component that makes an ajax GET request to the Yahoo weather API using axios. I am receiving a CORS error in that the preflight check… if I make the request using
jQuery.ajax()
to the same endpoint, the request is sent with no issues.
这表明 jQuery.ajax()
没有以触发预检的方式发出请求,但 axios 请求是。几乎可以肯定,axios 请求正在添加一个或多个自定义请求 header——我猜可能是 X-Requested-With
header*——而 jQuery.ajax()
不是。
* 更新: 原来在这个例子中被添加的 header 是 X-CSRF-TOKEN
.
要确切地知道发生了什么,请检查浏览器发送的 OPTIONS
请求——特别是 OPTIONS
请求中的 Access-Control-Request-Headers
请求 header。这将包含 axios 请求试图添加到请求中的任何自定义请求的名称 header。
您可以查看 header 和 OPTIONS
请求的其他详细信息,方法是进入浏览器 devtools 中的网络窗格并重新加载,然后检查那里的 OPTIONS
请求。
无论如何,有一种方法可以使该端点的请求无论如何都按预期工作。您可以通过 CORS 代理发出请求,方法是将前端代码更改为:
const proxyurl = "https://cors-anywhere.herokuapp.com/";
const endpoint = "https://query.yahooapis.com/v1/public/yql?q=select item.condition from weather.forecast where woeid in (select woeid from geo.places(1) where text='Sunderland') and u='c'&format=json";
const yapi = axios.create({
url: proxyurl + endpoint,
method: 'get',
withCredentials: false
});
这将通过 https://cors-anywhere.herokuapp.com 发送请求——浏览器的预检 OPTIONS
请求和您的 GET
请求。那里的后端将请求转发到 https://query.yahooapis.com/v1/public/yql
端点并接收响应。
那里的后端然后将 Access-Control-Allow-Origin
header 添加到响应中——在 OPTIONS
的情况下,还有 Access-Control-Allow-Headers
和 Access-Control-Allow-Methods
响应 headers——然后将其传递回您的请求前端代码。
然后浏览器将允许您的前端代码访问响应,因为带有 Access-Control-Allow-Origin
响应 header 的响应是浏览器所看到的。