Glassfish下Java REST服务AJAX跨域请求拦截问题求助
解决Glassfish 3.1.2下JQuery AJAX访问Java REST服务的CORS跨域问题
咱们先拆解下你遇到的问题里的几个关键误区,再一步步给出可行的解决方案:
首先要明确:你在客户端AJAX的beforeSend里设置Access-Control-Allow-Origin头是完全错误的——这个响应头是服务器返回给浏览器的权限标识,不是客户端请求时需要发送的,浏览器看到客户端发这个头反而会忽略,甚至干扰预检请求的正常处理。
一、修正客户端AJAX代码
去掉错误的请求头设置,同时简化冗余配置(JQuery里crossOrigin和crossDomain功能重复,保留核心配置即可):
$.ajax({ type: 'POST', url: webservice + "/webresources/ivi/syncPassphrase", data : JSON.stringify({ 'passPhrase' : passphrase }), xhrFields: { withCredentials: true }, dataType: 'json', async: true, // 强烈建议保持异步,同步请求会阻塞浏览器主线程 contentType: 'application/json; charset=utf-8', crossDomain: true, timeout: 20000, success: function(data){ syncData = data["output"]; console.log("xxx1 " + syncData); }, error: function(xhr, status, error) { console.log("xxx2 " + xhr.responseText + " | " + status + " | " + error + " | "); } });
二、修复服务器端CORS Filter
Glassfish 3.1.2搭配的Jersey 1.x对OPTIONS预检请求的处理有特殊要求——浏览器会在发送实际POST请求前先发一个OPTIONS请求验证跨域权限,如果你的Filter没正确处理这个请求,响应头就不会被正确添加。
修改Filter代码(添加OPTIONS请求处理)
@Override public void filter(final ContainerRequestContext requestContext, final ContainerResponseContext cres) throws IOException { // 注意:当客户端设置withCredentials: true时,Access-Control-Allow-Origin不能用*,必须指定具体客户端域名 cres.getHeaders().add("Access-Control-Allow-Origin", "http://111.111.111.111:8080"); cres.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization"); cres.getHeaders().add("Access-Control-Allow-Credentials", "true"); cres.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD"); cres.getHeaders().add("Access-Control-Max-Age", "1209600"); // 处理OPTIONS预检请求:直接返回200状态,无需转发到业务接口 String requestMethod = requestContext.getMethod(); if ("OPTIONS".equalsIgnoreCase(requestMethod)) { cres.setStatus(Response.Status.OK.getStatusCode()); cres.setEntity(null); // 清空响应实体,OPTIONS不需要返回业务内容 return; } }
确保Filter正确注册
- 如果用注解方式,给Filter类添加
@Provider注解; - 如果用web.xml配置,添加以下代码(替换成你的Filter类路径):
<filter> <filter-name>CORSFilter</filter-name> <filter-class>com.yourpackage.CORSFilter</filter-class> </filter> <filter-mapping> <filter-name>CORSFilter</filter-name> <url-pattern>/webresources/*</url-pattern> <!-- 匹配你的REST服务根路径 --> </filter-mapping>
三、验证与调试
重启Glassfish后,用Firefox开发者工具(F12)查看网络请求:
- 找到OPTIONS预检请求,确认响应头包含
Access-Control-Allow-Origin等你设置的权限头; - 查看后续的POST请求,确认响应头正常,且浏览器控制台不再出现CORS拦截错误。
关键注意点
当客户端设置xhrFields: { withCredentials: true }时,服务器的Access-Control-Allow-Origin绝对不能用*,必须指定客户端的实际域名(比如你代码里的http://111.111.111.111:8080),否则浏览器会直接拒绝响应,这是很多人踩过的坑。
内容的提问来源于stack exchange,提问作者Yohanes AI
相关产品推荐
相关产品推荐

