首页 文章

如何调试“请求的资源上没有'Access-Control-Allow-Origin'标头”

提问于
浏览
4

我在浏览器控制台上显示此错误:

XMLHttpRequest无法加载http:// localhost:8080 / api / login . 请求的资源上不存在“Access-Control-Allow-Origin”标头 . 因此不允许来源'http:// localhost:9009'访问 .

我正在使用的环境是:

  • Backend - Spring Boot

  • Front End - Angularjs

  • Web Server - 咕噜

在服务器上,我已经在请求和响应中定义标头:

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

4 回答

  • 0

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

    从4.2开始,Spring Framework支持使用全局配置的CORS或使用Filter - see this blog post for more information .

    如果您使用的是Spring Boot,版本1.3.0(即将发布)will integrate this support .

  • 1

    您需要在Web服务器上启用CORS(跨源资源共享) . 请参阅this resource .

    您需要将响应标头设置为:

    Access-Control-Allow-Origin: *
    

    This link具有设置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);
    
    }
    

    角度请求函数

    $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;
                }
    
            });
    
        }
    
  • 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() {
    
        }
    
    }
    
  • 1

    您还需要在角度代码中进行更新,以通过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所说,您希望对“*”保持谨慎,我强烈建议您将其替换为您的域名 .

相关问题