如何调试“请求资源未包含'Access-Control-Allow-Origin'头部信息”的问题。

4
我在浏览器控制台上看到了以下错误信息:
XMLHttpRequest无法加载http://localhost:8080/api/login。请求的资源中没有“Access-Control-Allow-Origin”标头。因此,源“http://localhost:9009”不允许访问。
我使用的环境是:
- 后端:Spring Boot - 前端:Angularjs - Web服务器:Grunt
在服务器上,我已经在请求和响应中定义了标头:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

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

        if (httpRequest.getMethod().equals("OPTIONS")) {
            httpResponse.setStatus(HttpServletResponse.SC_ACCEPTED);
            return;
        }
}

我已经在这个链接No 'Access-Control-Allow-Origin' header is present on the requested resource上找到了这个问题,但是没有找到合适的解决方案。

以下是浏览器网络图像:

enter image description here


不是直接回答你的问题,但是:1)当您将其部署到生产环境时,请小心使用“*”符号,2)请在进行此调用时向我们展示通过网络传输的标头(在浏览器中按F12然后选择“网络”选项卡可查看)。 - Marged
1
我已经上传了图片。 - Kamaldeep Singh
这很让人困惑。你难道不是在响应中设置头部吗?你的跟踪显示它们在请求中。 - Marged
4个回答

1

你的服务器应该为预检/实际CORS请求添加适当的CORS标头。我不建议实现自己的过滤器,因为这是一个相当复杂的规范。

从4.2开始,Spring框架支持全局配置或使用过滤器进行CORS - 请查看此博客文章了解更多信息

如果你正在使用Spring Boot,版本1.3.0(即将发布),将整合此支持


0

你的过滤器没问题,你应该将它作为一个组件包含进来,并放在可以被Spring扫描到的位置。

@Component
public class CORSFilter implements Filter{

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {

        HttpServletResponse response = (HttpServletResponse) res;
        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");
        chain.doFilter(req, res);

    }

    @Override
    public void destroy() {

    }

}

0

您需要在您的Angular代码中进行更新,以通过AJAX允许CORS。

myApp.config(['$httpProvider', function($httpProvider) {
        $httpProvider.defaults.useXDomain = true;
        delete $httpProvider.defaults.headers.common['X-Requested-With'];
    }
]);

如果上述方法不起作用,您可能还需要添加以下内容:
myApp.all('/*', function (request, response, next) {
    response.header("Access-Control-Allow-Origin", "*");
    response.header("Access-Control-Allow-Headers", "X-Requested-With");
    response.header("Access-Control-Allow-Methods", "GET, POST", "PUT", "DELETE");
    next();    
});

如@Marged所指出的,您需要注意“*”,我强烈建议用您的域名替换它。


0

您需要在您的Web服务器上启用CORS(跨域资源共享)。请参考这个资源

您需要将响应头设置为:

Access-Control-Allow-Origin: *

这个链接包含设置CORS所需的所有信息。

为所有域启用CORS并不是一个好的做法,因此在一切就绪后应该加以限制。

另一个解决方法是为cURL请求拥有一个单独的API

调用你自己API中的URL,并使用cURL或其他工具通过服务器端访问数据。我有一个目前正在工作的项目与相同的情况(Laravel + AngularJs)。

我的cURL请求远程身份验证示例代码:

代码采用Laravel-PHP格式,希望你能将其转换为你所使用的语言。

请求函数:

public function curlRequester($url,$fields)
    {
        // Open connection
        $ch = curl_init();

        // Set the url, number of POST vars, POST data
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );

        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);

        // Execute post
        $result = curl_exec($ch);

        // Close connection
        curl_close($ch);

        $result_json_decoded = json_decode($result, true);


        return $result_json_decoded;
    }

控制器函数

public function login()
{

    // set POST params
    $fields = array(
        'username' => Input::get('username'),
        'password' => Input::get('password')
    );
    $url = 'http://www.this-is-api-url.com/login';

    $result = $this->curl->curlRequester($url,$fields);

    return response()->json($result);

}

Angular请求函数

$scope.authCheck = function(){

        $http({
            url:'http://www.our-project-url/login',
            method:"post",
            data:{"username": "rameez", "password":"rameezrami"}
        })
        .success(function(response) {
            if(response.status==1){
                $location.path("/homepage");
            }else if(response.status==0){
                $scope.login_error_message_box = true;
                $scope.login_error_message_text =response.message;
            }

        });

    }

是的,我遵循了那个,但是找不到它滞后的错误。 - Kamaldeep Singh
嗨,从您发布的网络图片来看,似乎您在服务器端没有设置CORS ACCESS HEADER。 - Rameez Rami

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接