【问题标题】:No Access-Control-Allow-Origin header is present on the requested resource请求的资源上不存在 Access-Control-Allow-Origin 标头
【发布时间】:2014-01-19 19:37:01
【问题描述】:

我想访问来自同一个域但具有不同端口号的信息,为此我添加了Access-Control-Allow-Origin 和响应头。

Servlet 代码:(出现在 www.example.com:PORT_NUMBER 上)

String json = new Gson().toJson(list);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.setHeader("Access-Control-Allow-Origin", "*");//cross domain request/CORS
response.getWriter().write(json);

jQuery 代码:(出现在 www.example.com)

$.post('http://www.example.com:PORT_NUMBER/MYSERVLET',{MyParam: 'value'}).done(function(data)
{
    alert(data);
});

我多次收到此错误(在控制台中):

XMLHttpRequest cannot load 'http://www.example.com:PORT_NUMBER/MYSERVLET'
No 'Access-Control-Allow-Origin' header is present on the requested resource.

这个错误主要是在$.post 被执行时第一次发生。第二次允许。

我的问题是servletjQuery 代码中是否缺少?

任何建议将不胜感激。

更新1

我变了:

response.setHeader("Access-Control-Allow-Origin", "*");

收件人:

response.setHeader("Access-Control-Allow-Origin", "http://www.example.com");

然后我在控制台中收到此错误:

XMLHttpRequest cannot load http://www.example.com:PORT_NUMBER/MyServletName
The 'Access-Control-Allow-Origin' whitelists only 'http://www.example.com'
Origin 'http://www.example.com' is not in the list,
and is therefore not allowed access.

[注意:白名单和来源相同,但仍然报错。它有时有效,有时会出现上述错误。]

如果您需要更多信息,请告诉我。

【问题讨论】:

  • 这很简单:您的服务器响应不包含正确的 CORS 标头。这不是浏览器错误,也没有客户端代码问题。如果您想深入了解这一点,请更仔细地跟踪您的服务器端代码,以确保标头始终包含在响应中。您应该首先在客户端和服务器之间插入一个代理来自己检查标头。

标签: javascript java jquery ajax cors


【解决方案1】:

$.post() 方法中缺少“json”数据类型:

$.post('http://www.example.com:PORT_NUMBER/MYSERVLET',{MyParam: 'value'})
        .done(function(data){
                  alert(data);
         }, "json");
         //-^^^^^^-------here

更新:

试试这个:

response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));

【讨论】:

  • 解析响应不是这里的问题。问题是响应不包含正确的 CORS 标头。这表明存在服务器端问题。
  • @RayNicholus 我的问题是 servlet 或 jQuery 代码中是否缺少? 所以我建议 $.post() 方法中缺少 dataType,因为响应是来自服务器。
  • 同样,问题是响应中缺少标头。响应的内容在这里无关紧要。问题中的代码甚至没有尝试解析响应。
【解决方案2】:

解决方案
我没有使用setHeader 方法,而是使用了addHeader

response.addHeader("Access-Control-Allow-Origin", "*");

以上行中的* 将允许访问所有域,仅允许访问特定域:

response.addHeader("Access-Control-Allow-Origin", "http://www.example.com");

有关 IEhere。

【讨论】:

  • 如果我们要允许多个域怎么办?第二个参数会是这样吗? “example1.com","http://www.example2.com”还是别的什么?
  • @MuhammadNoman 你试过两次写 addHeader 吗?我认为addheader 方法添加了标题并且不会覆盖现有的。
  • 如果我想添加两个域怎么办?我不确定我的想法是否正确,但如果我需要允许 cors 访问两个特定域,例如 www.example1.com 和 www.example2.com。标头应该类似于 response.addHeader("Access-Control-Allow-Origin", "example1.com, example2.com"); ?或者我该怎么做?
【解决方案3】:

我在spring.io找到了解决方案,像这样:

    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "x-requested-with");

【讨论】:

    【解决方案4】:

    在您的 servlet 上,只需覆盖您的 servlet 的服务方法,以便您可以为所有 http 方法(POST、GET、DELETE、PUT 等)添加标头。

    @Override
        protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
    
            if(("http://www.example.com").equals(req.getHeader("origin"))){
                res.setHeader("Access-Control-Allow-Origin", req.getHeader("origin"));
                res.setHeader("Access-Control-Allow-Headers", "Authorization");
            }
    
            super.service(req, res);
        }
    

    【讨论】:

      猜你喜欢
      • 2013-11-29
      • 2014-07-28
      • 2013-12-07
      相关资源
      最近更新 更多