当前位置: 首页 > 知识库问答 >
问题:

CORS过滤器未按预期工作

子车文康
2023-03-14
Failed to load resource: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63343' is therefore not allowed access. http://localhost:8080/register?password=&username=
XMLHttpRequest cannot load http://localhost:8080/register?password=&username=. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63343' is therefore not allowed access.
var charmanderServices = angular.module('charmanderServices', ['ngResource']);

var hostAdress = "http://localhost:8080";

charmanderServices.factory("register", ["$resource",
    function($resource){
        console.log('in service');
        return $resource(hostAdress + "/register", {}, {
            'registerUser' : { method: 'POST', isArray: false,
            params: {
                username: '@username',
                password: '@password'
            }
            },
            headers : {'Content-Type' : 'application/x-www-form-urlencoded'}
        });

    }
]);
@Component
public class SimpleCORSFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
         //This is not even printing
        System.out.println("Cheers lads, I'm in the filter");
        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, X-Auth-Token, Content-Type");
        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {}

    public void destroy() {}
}
<web-app version="3.0"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
         http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd">

    <display-name>Project</display-name>


    <!-- Load Spring Contexts -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- CORS Filter -->

    <filter>
        <filter-name>cors</filter-name>
        <filter-class>com.robin.filters.SimpleCORSFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>cors</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:/spring/applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>
@Controller
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping(value = "/register" , method= RequestMethod.POST, produces = "application/json")
    @ResponseBody
    public boolean register(@RequestParam(value = "username") String username, @RequestParam(value = "password") String password){
        System.out.println("Im in register hurray");
        return userService.register(username, password);
    }
}

更新:我尝试将过滤器实现为OncePerRequestFilter,但仍然不起作用。有人能在这里进一步帮助我吗?

更新2:也试过这个,http://software.dzhuvinov.com/cors-filter-installation.html,运气不好

更新#3:这是我在控制台中的输出,我可以看到响应没有添加任何标题:

Request URL:http://localhost:8080/register?password=g&username=g
Request Method:OPTIONS
Status Code:200 OK
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,nl;q=0.6
Access-Control-Request-Headers:accept, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:localhost:8080
Origin:http://localhost:63343
Referer:http://localhost:63343/Project/index.html?uName=g&uPassword=g&uPasswordConfirm=g
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36
Query String Parametersview sourceview URL encoded
password:g
username:g
Response Headersview source
Allow:GET, HEAD, POST, PUT, DELETE, OPTIONS
Content-Length:0
Date:Fri, 04 Apr 2014 09:50:35 GMT
Server:Apache-Coyote/1.1
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
    <context:component-scan base-package="com.robin"/>
    <mvc:annotation-driven/>
    <!-- Hibernate Session Factory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="packagesToScan">
            <array>
                <value>com.robin.model</value>
            </array>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
            </props>
        </property>
        <property name="annotatedClasses">
            <list>
                <value>com.robin.model.User</value>
            </list>
        </property>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>

    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <!--Driver for mysqldb -->
    <import resource="mysql-context.xml"/>
</beans>
charmanderControllers.controller('registerController', ['$scope', 'register',

    function($scope, register){
    $scope.username = '';
    $scope.password = '';

    $scope.register = function () {
        register.registerUser({'username': $scope.username, 'password': $scope.password}).$promise.then(function(data){
            switch(data.response){
                case true:
                    //succes
                    $scope.registered = true;
                    $scope.userExists = false;
                    break;
                case false:
                    //user exists
                    $scope.registered = false;
                    $scope.userExists = true;
                    break;
            }
            console.log(data.response);
        })
    };

        $scope.checkValidRegister = function (invalid) {
            console.log(invalid);
            console.log($scope.passwordConfirm);
            console.log($scope.password);
            console.log($scope.username);
            if (invalid || $scope.password != $scope.passwordConfirm) {
                console.log("I shouldnt be here");
                $scope.validation = true;
                if ($scope.password != $scope.passwordConfirm) {
                    $scope.passwordError = true;
                }
            } else {
                register();
            }
        };
}]);

register.html

 <h1>Register now!</h1>
    <form method="post" class="register" novalidate>
        <p>
            <label for="email">E-mail:</label>
            <input type="text" name="login" id="email" placeholder="E-mail address..." required ng-model="username">
        </p>

        <p>
            <label for="password">Password:</label>
            <input type="password" name="password" id="password" placeholder="Password..."
                   required ng-model="password">
        </p>

        <p>
            <label for="confirm_password">Confirm password: </label>
            <input type="password" name="confirm_password" id="confirm_password" placeholder="Confirm password..."
                   required ng-model="passwordConfirm">
            <span ng-show="passwordError">Passwords do not match!</span>
        </p>

        <p class="register_submit">
            <button type="submit" class="register-button" ng-click="checkValidRegister()">Register</button>
        </p>

    </form>

共有1个答案

鱼阳伯
2023-03-14

您的代码和配置总体上看起来不错,我能够在本地环境中运行它。请从SimpleCorsFilter中删除@component注释,因为您将它用作普通Servlet过滤器,并且它不需要成为Spring上下文的一部分。

UPD.Tomcat7有自己的CORS过滤器实现。您可以查看文档和源代码了解更多细节。我已经修改了标题,以反映其默认配置,现在应该按预期工作。

由于您已经使用了Spring,并且如果您使用的是Spring4.2或更高版本,那么您不需要CorsFilter,而只需使用CrossOrigin注释控制器方法即可。这里有一篇关于这一点的优秀文章,值得一读。

下面是我使用普通过滤器实现的工作示例:

控制器:

@Controller
public class UserController {

    private static Logger log = Logger.getAnonymousLogger();

    @RequestMapping(
            value = "/register",
            method = RequestMethod.POST,
            consumes = "application/x-www-form-urlencoded")
    @ResponseBody
    public String register(@RequestParam(value = "user") String username,
                           @RequestParam(value = "password") String password) {
        log.info(username + " " + password);
        return "true";
    }

}

过滤器:

public class CorsFilter implements Filter {

    private static final Logger log = Logger.getAnonymousLogger();

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

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("Adding Access Control Response Headers");
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, HEAD, OPTIONS");
        response.setHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}
    <filter>
        <filter-name>cors</filter-name>
        <filter-class>com.udalmik.filter.CorsFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>cors</filter-name>
        <url-pattern>/register</url-pattern>
    </filter-mapping>
$(document).ready(function() {
    $('#buttonId').click(function() {
        $.ajax({
            type: "POST",
            url: "http://localhost:8080/register",
            success : function(data){
                console.log(data);
            },
            data : {
                user : 'test.user@acme.com',
                password : 'password'
            }
        });
    }
}
 类似资料:
  • 问题内容: 这是我的配置: 现在,当我尝试访问我的API时,出现以下错误: 我在做什么错,以及如何正确配置CORS标头以避免发生此问题? 问题答案: 我已经通过创建新的CORS过滤器解决了此问题: 并将其添加到安全配置中: 更新-如今,我使用了更现代的方式切换到:

  • 我正在使用spring Roo并希望访问Controller类中的一个bean,该类在ApplicationContext.xml中具有以下配置: 配置类本身是: 在我的Controller中,我认为一个简单的Autowired注释应该可以完成这项工作 在启动过程中,spring在setSkipWeeks方法中打印消息。不幸的是,每当我在控制器中调用config.getSkipWeeks()时,它

  • 当我运行以下程序时,它只打印 然而,从Java 8的equalsIgnoreCase文档中我们发现: 如果以下至少一项为真,则两个字符c1和c2被视为相同的忽略情况: •对每个字符应用java.lang.character.ToUpperCase(char)方法会产生相同的结果 所以我的问题是为什么这个程序不打印 在这两种操作中,都使用了大写字符。

  • 我试图使用来传输我根据前面的问题设置的自定义标头。 我在文件中读到... 我的属性包括:

  • 我正在和selenium一起工作,刮一些数据。 有一个按钮在页面上,我正在点击说“Custom_Cols”。这个按钮为我打开了一个窗口,我可以在那里选择我的列。 我的问题是为什么新窗口上的元素不可见,即使我正在等待元素的可见。补充一下,我已经尝试增加延迟时间,但我还是会偶尔出现这个错误。 我的密码在这里