2017-02-20 68 views
1

我正在使用JavaScript。XMLHttpRequest在控制台上工作,但在脚本标记中使用时,因为js文件显示CORS错误

这里是我的代码

const BASE_URL = "https://example.com/api"; 
export class BankApi { 

    constructor(XMLHttpRequest){ 
     this.xhr = XMLHttpRequest; 
    } 

    getBankList(callback){ 
     this.xhr.open("GET", BASE_URL+"/listbanks", true); 
     this.xhr.setRequestHeader('Content-Type', 'application/json'); 
     this.xhr.send(null); 
     this.xhr.onreadystatechange = function(){ 
      if (this.readyState != 4) return; 

      if (this.status == 200) { 
       var data = JSON.parse(this.responseText); 
       callback(data); 
      } 
     }; 
    } 
} 

我已经写代码ES6但我有使用变换ES2015模块-UMD min.js。 我已经包括在客户端项目

当我打电话

var bankApi = new BankApi(new XMLHttpRequest()); 
bankApi.getBankList(function(data){ 
    console.log(data); 
}) 

我得到的错误

XMLHttpRequest cannot load https://example.com/api/listbanks. 
Response to preflight request doesn't pass access control check: 
No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'https://engineeringqna.com' is therefore not allowed access. 

但这个文件,当我做同样的镀铬形式的调试器控制台https://engineeringqna.com域无错误。

var xhr = new XMLHttpRequest(); 
xhr.open("GET","https://example.com/api/listbanks",true); 
xhr.setRequestHeader('Content-Type', 'application/json'); 
xhr.onreadystatechange = function(){ 
if (xhr.readyState == 4) 
    { 
     if (xhr.status == 200) { 
      console.log(data); 
     } 
     else { 
     alert("xhr Errors Occured"); 
     } 
    } 
} 
xhr.send(null); 

没有错误。我在控制台中获取数据。 任何人都可以请解释我在这里发生了什么?

谢谢。

+1

如果其他域未明确允许,则浏览器不会让来自您的域的代码访问来自*不同*域的内容。 – Pointy

+0

我同意。但是服务器有配置接受跨域请求。我无法理解如何在调试器控制台中复制和粘贴代码时工作,并且当代码包含在项目中并从浏览器控制台调用时不工作。另外我试图向浏览器控制台注入角度js $ http。在这里,当我发出$ http.get请求时,我得到了没有问题的结果。 –

+0

错误* No'Access-Control-Allow-Origin'标题出现在被请求的资源上*表示服务器没有**没有配置来接受跨域请求。 – Pointy

回答

1

当您设置content-typeapplication/json这触发CORS“预检” - 一个OPTIONS请求,必须由服务器

处理在这种情况下,服务器显然不处理OPTIONS请求,这导致在响应中没有访问控制允许来源,导致请求无效

没有必要设置该头文件,特别是在GET请求中(您没有发送任何内容,那么为什么指定一个内容类型? )

通过删除行

this.xhr.setRequestHeader('Content-Type', 'application/json'); 

浏览器将不发送预检要求,因此API应该像预期的那样

取决于响应,你可能想overrideMimeType()方法重写响应MIME类型 - 然而,因为请求作品在控制台中,您可能不需要这个

+0

谢谢@jaromanda。像魅力一样工作。此外,我恳请您更新关于如何在服务器端处理OPTIONS请求的答案简报。 –

+0

如何处理服务器端的OPTIONS取决于服务器环境 - 每个解释如何处理CORS预检请求的环境都有大量资源 - 我不打算为他们研究**全部** –

相关问题