Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/416.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何提出CORS请求_Javascript_Ajax_Reactjs_Cors - Fatal编程技术网

Javascript 如何提出CORS请求

Javascript 如何提出CORS请求,javascript,ajax,reactjs,cors,Javascript,Ajax,Reactjs,Cors,我正在用React.js制作一个天气应用程序,我想请求CORS从天气地下网站获取数据。 我想要的是获得一个城市名称,使用自动完成API查找城市并获取该城市的数据 问题是,每次我给出一个城市名称(例如:德黑兰),xhr.onerror事件处理程序都会运行,我得到以下错误: 无法加载XMLHttpRequesthttp://autocomplete.wunderground.com/aq?query=tehran. 请求的资源上不存在“Access Control Allow Origin”标头。起

我正在用React.js制作一个天气应用程序,我想请求CORS从天气地下网站获取数据。 我想要的是获得一个城市名称,使用自动完成API查找城市并获取该城市的数据

问题是,每次我给出一个城市名称(例如:德黑兰),xhr.onerror事件处理程序都会运行,我得到以下错误:

无法加载XMLHttpRequesthttp://autocomplete.wunderground.com/aq?query=tehran. 请求的资源上不存在“Access Control Allow Origin”标头。起源'http://localhost:3000因此,不允许访问

这是我获取数据的代码:

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);
        });
    }
}
应用程序的屏幕截图:

这里有一个简单的react组件,它使用查询参数调用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>
        )
    }
}
因为http://autocomplete.wunderground.com/aq?query=tehran 如果不发送Access Control Allow Origin响应标头,则必须更改前端代码以通过代理发出请求。通过更改“天气”\u“地下”\u“自动完成”值来执行此操作:

https://cors-anywhere.herokuapp.com/http://autocomplete.wunderground.com/…URL将导致请求转到https://cors-anywhere.herokuapp.com,一个公共CORS代理,将请求发送到http://autocomplete.wunderground.com…您想要的URL

该代理获取响应,获取该响应并向其添加访问控制允许源响应头,然后最终将其作为响应传递回请求的前端代码

最后,由于浏览器看到带有Access Control Allow Origin响应头的响应,因此浏览器允许前端JavaScript代码访问响应

或者使用来自或类似的代码来设置您自己的代理

在这种情况下,您需要一个代理,因为http://autocomplete.wunderground.com/…本身不发送Access Control Allow Origin响应头,在这种情况下,浏览器将不允许前端JavaScript代码跨源访问来自该服务器的响应

有更多的细节

顺便说一句,您可以使用curl或其他工具来验证服务器是否未发送标头:

$curl-i-H'原点:http://localhost:3000' \ 'http://autocomplete.wunderground.com/aq?query=tehran' HTTP/1.1200ok 内容类型:application/json;字符集=utf-8 内容长度:2232 连接:保持活力 {结果:[ { 姓名:伊朗德黑兰达什特, …
请注意,那里的响应头中没有访问控制Allow Origin。您一定要使用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)
});

您可以在此处了解更多信息:

如果您在发出CORS请求时遇到问题,请使用此简单的允许控件允许来源


这将允许您发出CORS请求,而无需在headers/config中添加任何额外参数。

您可以尝试执行axios.getrequestAutoComplete.thenfunctionresponse{console.logresponse;}.catchfunctionerror{console.logerror;};我在发布此问题之前做了此操作,但它不起作用。是否要屏幕共享?这样我可以更好地检查此问题。您请求资源的服务器没有设置必要的访问控制标头,除非有人修改后端,否则无法解决此问题,而访问控制允许源只是其中之一跨源资源所需的标头sharing@user3408151它之所以有效,是因为您直接将地址输入了地址栏,但这里OP使用的是ajax,这是另一回事
var myInit = { 
    method: 'GET',
    mode: 'cors',
    credentials: 'include'
};

fetch(YOUR_URL, myInit)
.then(function(response) {
    return response.json();
})
.then(function(json) {
    console.log(json)
});