浏览器中不允许跨域调用

Posted

技术标签:

【中文标题】浏览器中不允许跨域调用【英文标题】:Cross Origin call is not allowing in browser 【发布时间】:2017-01-23 08:33:35 【问题描述】:

我正在尝试将一个应用程序调用到另一个我得到的应用程序,并且错误为“预检响应中的 Access-Control-Allow-Headers 不允许请求标头字段授权”。在我的后端,我使用了下面提到的以下代码

     List<String> originList = Arrays.asList(origins.trim().split("( )*,( )*"));
    String origin = request.getHeader("Origin");
    if (originList.contains(origin)) 
        originAllow = origin;
     else 
        originAllow = originList.get(0);
    
     response.setHeader("Access-Control-Allow-Origin", originAllow);
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "PUT, POST, GET, OPTIONS, DELETE, PATCH");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "x-requested-with, accept, authorization");
    response.setHeader("Access-Control-Expose-Headers", "Location");

在 originAllow 中,我传递了我试图访问的 url,但出现以下错误,

     XMLHttpRequest cannot load http://<<url>>. Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response.

请找到浏览器请求和响应头, 响应头

Access-Control-Allow-Headers:x-requested-with, content-type
    访问控制允许方法:获取选项
    访问控制允许来源:*
    访问控制最大年龄:3600
    允许:GET、HEAD、POST、PUT、DELETE、TRACE、OPTIONS、PATCH
    连接:关闭
    内容长度:0
    内容类型:文本/纯文本;字符集=UTF-8
    服务器:Apache-Coyote/1.1
    X-应用程序上下文::8080
    
请求标头 接受:/ 接受编码:gzip、deflate、sdch 接受语言:en-US,en;q=0.8,ms;q=0.6 Access-Control-Request-Headers:授权,x-requested-with 访问控制请求方法:GET 连接:保持活动 主机:myrestapi-dev 来源:http://localhost:9000 推荐人:http://localhost:9000/ 用户代理:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/52.0.2743.116 Safari/537.36

选项 ?page=0&search_param=test&size=10,desc HTTP/1.1 主机:myrestapi-dev 连接:保持活动 访问控制请求方法:GET 来源:http://localhost:9000 用户代理:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Access-Control-Request-Headers:授权,x-requested-with 接受:/ 推荐人:http://localhost:9000/ 接受编码:gzip、deflate、sdch 接受语言:en-US,en;q=0.8,ms;q=0.6

我在 localhost:port 中运行应用程序,而另一个应用程序正在使用协议、主机不同的部署 url。

请让我知道我需要添加什么来从 ui(angular) 访问 url 以进行授权而且它在其他浏览器中工作但在 chrome 中不工作

【问题讨论】:

响应是 httpResponse 还是 ServletResponse?请从浏览器中提供请求标头。 Access-Control-Allow-Headers:x-requested-with, content-type for reponse 和 Access-Control-Request-Headers:authorization, x-requested-with for request 被提及并在后端我添加了“Access-Control-Allow-Headers”、“x-requested-with、content-type、accept、authorization”,但它不起作用 【参考方案1】:

这是因为您的服务器不允许授权标头。 解决它:

response.setHeader("Access-Control-Allow-Headers", "Content-Type, authorization");

应该可以帮助你。因为我不确定你的后端,所以我需要多解释一下。 这是因为由服务器指定它接受跨域请求(并且它允许 Content-Type 请求标头)。此外,您需要从同一域进行 AJAX 调用或进行服务器端更改,允许来自外部域的请求。要解决此问题,您需要通过在标题中允许您的外部域来更改 http://yourdomain.com 的标题:

Access-Control-Allow-Origin: *

1-ref1

2-ref2

AngularJs 中的可能解决方案。:在 Angular 中使用 JSONP

AngularJS $http 服务有一个名为“jsonp”的内置方法。

var url = "some REST API Url" + "?callback=JSON_CALLBACK";

$http.jsonp(url)
    .success(function(data)
       // whatever 
    );

此外,url 必须附加 ?callback=JSON_CALLBACK。

我将使用 JSONP 扩展此解决方案

exampleurl = 'http://wikidata.org/w/api.php?whatever....&format=json'

 //Number 1 : 
 $.ajax(
  dataType: "jsonp",
  url: exampleurl ,
  ).done(function ( data ) 
  // do whatever
);
//Number 2 : 
$.ajax(
  dataType: "json",
  url: exampleurl + '&callback=?',
  ).done(function ( data ) 
  // do whatever
);
//Number 3 : 
$.getJSON( exampleurl + '&callback=?', function(data) 
  // do whatever
);

更多信息

1-getJson

2-$.Ajax

【讨论】:

添加内容类型后,我也遇到了同样的错误,我已经提供了 Access-Control-Allow-Origin: http:// 。请让我知道是否需要任何其他更改 我更新了我的帖子。但我相信这是服务器端问题,但是您可以继续使用 Angular 中的新解决方案。 Access-Control-Allow-Origin: * - 这几乎总是一个坏主意,因为它会打开您的网站以接收来自任何地方的请求。除非您完全确定自己想要这个,否则只允许您信任的来源会更安全。 @DaveMongoose 确实,这是不好的做法。

以上是关于浏览器中不允许跨域调用的主要内容,如果未能解决你的问题,请参考以下文章

跨域解决方法

ajax 跨域

允许浏览器跨域访问web服务端的解决方案

JSAJAX跨域-被调用方与调用方解决方案

AJAX跨域问题解决方法——被调用方解决跨域

web api 跨域请求,ajax跨域调用webapi