我正在使用REST与由Keycloak保护的JAVA后端(Thorntail微服务)进行通信的前端工作。使用GET和POST没问题,但是根据我的设置,尝试DELETE会返回不同的错误。我的默认CorsFilter.java文件没有设置:
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;
@Provider
public class CorsFilter implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) {
}
}
我的React REST功能:
static deleteCourier = function (origin, courierNumber, endpoint, data, requestListener) {
keycloak.updateToken(5).then(function () {
const request = new XMLHttpRequest();
request.open("DELETE", HTTP_SCHEME + "://" + backendUrl + endpoint + "/" + origin + "/" + courierNumber);
request.setRequestHeader('Authorization', 'Bearer' + keycloak.token);
request.send();
}).catch(function () {
console.log('Failed to refresh the token, or the session has expired');
keycloak.init({onLoad: 'login-required'}).success(function (authenticated) {
if (authenticated) {
Rest.deleteCourier(origin, courierNumber, endpoint, data, requestListener);
} else {
console.log('kc not authenticated');
}
}).error(function () {
console.log('kc init failed');
});
}).then(function () {
Rest.updateData(data, requestListener, endpoint)
});
};
调用后端的REST API:
import javax.ejb.EJB;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.OPTIONS;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@Path("/device")
public class DeviceEndpoint {
@DELETE
@Path("/{origin}/{courierNumber}")
public Response delete(
@PathParam("origin") String origin,
@PathParam("courierNumber") String courierNumber) {
try {
deviceBF.removeCourier(origin, courierNumber);
} catch (PhoenixClientException e) {
return Response.ok(new WebApplicationException(e)).build();
}
return Response.ok().build();
}
}
在Keycloak中,“ Web Origins”设置为“ *”。
使用此设置GET和POST可按预期工作。尝试删除设备时,浏览器中的“网络”标签显示以下状态:“(已取消)”和“(从Google Chrome浏览器中复制)”:
fetch(“ http://192.168.0.66:8282/auth/realms/customer/protocol/openid-connect/auth?response_type=code&client_id=mystique&redirect_uri=http%3A%2F%2F192.168.0.66%3A8080%2Fmystique%2Frest%2Fdevice%2Fdts%2Fd&state=22a1dba6-e12e-4852-8cba-0f86a4799d4f&login=true&scope=openid”,{“ credentials”:“ omit”,“ referrer”:“ http://localhost:3000/”,“ referrerPolicy”:“ no-referrer-when-downgrade”,“ body “:null,” method“:” DELETE“,” mode“:” cors“}});
控制台输出为:
CORS策略已阻止从来源“ http://192.168.0.66:8080/mystique/rest/device/dts/d”访问“ http://localhost:3000”处的XMLHttpRequest:请求的资源上没有“ Access-Control-Allow-Origin”标头。
GET和POST请求在实际请求之前发送OPTIONS请求。在这种情况下,不会发送任何此类OPTIONS请求。
当我将控制台输出放到我的REST API时,我可以看到它没有被调用。但是路径应该没问题。通过Postman测试了REST API,一切正常。
如果我修改CorsFilter.java文件并添加例如:
responseContext.getHeaders().add(
"Access-Control-Allow-Origin", "http://localhost:3000");
...浏览器控制台向我显示:
CORS策略已阻止从源“ http://192.168.0.66:8080/mystique/rest/websocket-auth/token”访问“ http://localhost:3000”处的XMLHttpRequest:“ Access-Control-Allow-Origin”标头包含多个值“ http://localhost:3000” ,http://localhost:3000”,但只允许一个。
我已经搜索了我的代码以及所有配置文件中的第二个条目,但一无所获。我不知道它是哪里来的。
在CorsFilter.java中添加以下内容似乎无效。
responseContext.getHeaders().add(
"Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS");
除了先前描述的行为外,快递员所属的设备也被删除。我不确定这是否与CORS的问题相对应,还是一个单一的问题。在不删除信使的情况下更改设备数据(也可以通过REST完成)按预期工作。但是在更新之前删除快递将删除我的设备。
我希望任何人都可以帮助我。