【问题标题】:How to send application/json jQuery ajax request in jaxrs without having ‘Access-Control-Allow-Origin’ missing error如何在 jax rs 中发送 application/json jQuery ajax 请求而不会出现“Access-Control-Allow-Origin”缺失错误
【发布时间】:2017-12-25 18:06:16
【问题描述】:

我的问题是当我从浏览器向 jaxrs api 服务器发送请求时,预检请求失败了

跨域请求被阻止:同源策略不允许读取位于https://localhost:9091/api/employee/add 的远程资源。 (原因:CORS 标头“Access-Control-Allow-Origin”缺失)。

我不明白为什么我无法使预检请求成功。我的邮递员请求成功。但是当从浏览器发送请求时,它正在下降。

Ajax 请求:

              $.ajax({


                type: "POST",
                url: "https://localhost:9091/api/employee/add",
                cache: false,
                data:JSON.stringify(employeeJSONObj),
                dataType: "json",
                contentType: 'application/json',

                success: function(response){


                });

Json 有效载荷:

{   
    "employeeName":"Name3",
    "nRIC":"NRIC3",
    "dateOfBirth":"2017-01-02",
    "address":"Address",
    "salaryMode":"Monthly",
    "bankAccount":"Bank Account",
    "appointmentAs":"Security Supervisor (SS)",
    "nationality":"Malaysian",
    "maritalStatus":"Married",
    "sex":"Female",
    "nextOfKin":"Next Of kin",
    "mobilePhone":"Mobile Phone",
    "profilePicture":null,
    "document":null
}

Jersy jaxrs API 服务器集成:

@POST
    @Consumes({ MediaType.APPLICATION_JSON})
    @Produces({ MediaType.APPLICATION_JSON})
    @Path("add")
    public Response addEmployee(Employee employee) {

        EmployeeImpl employeeImpl =
                (EmployeeImpl) context.getBean("employeeImpl");


        if (employeeImpl.validateEmployeeDetails(employee)) {

            employeeImpl.addEmployee(employee);
            employee.setSuccessMessage("Employee added successfully");

        }else{

            employee.setErrorMessage("employee detail insertion failed due to invalid" +
                    " inputs, please recheck inputs and retry");

            return Response.ok().status(Response.Status.BAD_REQUEST)
                    .entity(employee)
                    .header("Access-Control-Allow-Origin", "*")

                    .header("Access-Control-Allow-Methods", "POST, OPTIONS")
                    .header("Access-Control-Allow-Headers","Content-Type")
                    .build();

        }


        return Response.ok()
                .entity(employee)
                .header("Access-Control-Allow-Origin", "*")
                .header("Access-Control-Allow-Methods", "POST, OPTIONS")
                .header("Access-Control-Allow-Headers","Content-Type")
                .build();


    } 

Maven 依赖:

        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-server</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-json</artifactId>
            <version>1.18.1</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-grizzly2</artifactId>
            <version>1.8</version>
        </dependency>

请求标头:

Host: localhost:9091
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Origin: http://localhost:8080
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

【问题讨论】:

  • 不熟悉球衣,但似乎您的后端没有在 OPTIONS 请求上添加 CORS 标头。邮递员不受 CORS 限制,也不会将它们作为预检发送
  • 我应该如何在 OPTIONS 请求中添加 CORS 标头
  • 正如我所说,我对球衣不熟悉,但应该很容易研究。阅读 CORS 的工作原理
  • 您的 grizzly 容器服务器使用哪个端口? 8080 还是 9091?

标签: jquery json ajax rest jersey


【解决方案1】:

如果是您的测试应用,您可以使用Allow-Control-Allow-Origin chrome 扩展来启用允许交叉请求。

问题在于同时使用8080和9091端口。

Host: localhost:9091 
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Origin: http://localhost:8080

并检查this

更新:

出现此问题的原因是我没有在grizzle服务器中注册CORSFilter,在grizzle中注册CORSFilter后可以通过以下方式解决问题

需要按照如下方式创建一个CORSFilter类

public class CORSFilter implements ContainerResponseFilter {
@Override
public ContainerResponse filter(ContainerRequest request,
                                ContainerResponse response) {

    response.getHttpHeaders().add("Access-Control-Allow-Origin", "*");
    response.getHttpHeaders().add("Access-Control-Allow-Headers",
            "origin, content-type, accept, authorization," +
                    "access-control-allow-origin," +
                    "Access-Control-Allow-Credentials");
    response.getHttpHeaders().add("Access-Control-Allow-Methods",
            "GET, POST, PUT, DELETE, OPTIONS");

    response.getHttpHeaders().add("Access-Control-Expose-Headers","authorization,errorMessage,successMessage");


    return response;
   }
}

注册 CORSFilter

ResourceConfig rc=new PackagesResourceConfig("hms.test.automation.system.tc.manager.resources"); // register resources
    // Packages and exception mappers

    rc.getContainerResponseFilters().add(CORSFilter.class);

【讨论】:

  • 我不这么认为,你能建议我如何改变它
  • 您应该提供您的 grizzly 服务器启动方法。你试过扩展吗?
  • 是的,我使用了扩展,它工作正常。但我该怎么做“你应该提供你的灰熊服务器启动方法”
  • 尚不清楚您已发布的上述代码中发生了什么。我在 Maven 依赖项中看到了 grizzly。请问灰熊服务器在哪里运行?只是想弄清楚。
  • grizzle 服务器运行在 9091 端口,客户端运行在 8080 端口
猜你喜欢
  • 1970-01-01
  • 2014-02-01
  • 2013-04-26
  • 1970-01-01
  • 1970-01-01
  • 2013-05-16
  • 2013-05-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多