远程托管时 Spring REST api 不起作用
Posted
技术标签:
【中文标题】远程托管时 Spring REST api 不起作用【英文标题】:Spring REST api not working while hosted remotely 【发布时间】:2015-11-08 15:47:30 【问题描述】:我写了一个春季休息服务。当我在localhost
上运行它时,它运行良好
$.ajax(
url:"http://localhost:8080/api/v1.0/basicSignup",
type:"POST",
contentType:"application/json",
但是当我尝试并托管在某个远程服务器上时
$.ajax(
url:"http://X.X.X.X/api/v1.0/basicSignup",
type:"POST",
contentType:"application/json",
它抛出错误
在铬
XMLHttpRequest cannot load http://X.X.X.X/api/v1.0/basicSignup.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:8084' is therefore not allowed access.
在控制台中我看到Method
选项卡中显示options
在 Mozilla 中也显示OPTIONS
。
Response Headersview source
Allow GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Content-Length 0
Date Sat, 15 Aug 2015 15:15:07 GMT
Server Apache-Coyote/1.1
Request Headersview source
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-us,en;q=0.5
Access-Control-Request-He... content-type
Access-Control-Request-Me... POST
Cache-Control no-cache
Connection keep-alive
DNT 1
Host X.X.X.X
Origin null
Pragma no-cache
User-Agent Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:13.0) Gecko/20100101 Firefox/13.0.1
【问题讨论】:
docs.spring.io/spring/docs/current/spring-framework-reference/… 【参考方案1】:正如@JB 的评论所说,您可能需要实现CORS。基本上,single origin policy 不允许来自一个域的 javascript,比如 http://localhost:8084
对另一个域进行 AJAX 调用,比如默认情况下是 http://X.X.X.X
。有一些机制可以处理这个问题,但人们似乎更喜欢 CORS,因为通常它看起来最方便和强大。
Spring Lemon 详细展示了如何使用 CORS。以下是我另一个项目的示例:
在客户端代码中,我最初会设置这些 ajax 选项(或与每个调用一起)
$.ajaxSetup( // Initialize options for AJAX calls
crossDomain: true,
xhrFields:
withCredentials: true
...
);
在服务器端,有一个过滤器来设置 CORS 标头。 Spring 的最新版本(将与 Spring Boot 1.3 一起提供)有一个 easier way 用于在服务器端配置 CORS。但是,在一个使用 Spring Boot 1.2 的项目中,我会这样:
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCorsFilter implements Filter
@Value("$applicationUrl:http://localhost:8084")
String applicationUrl;
public void doFilter(ServletRequest req,
ServletResponse res,
FilterChain chain)
throws IOException, ServletException
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin",
applicationUrl); // "*" does not work when withCredentials = true;
response.setHeader("Access-Control-Allow-Methods",
"GET, POST, PUT, PATCH, DELETE, OPTIONS");
response.setHeader("Access-Control-Max-Age",
"3600");
response.setHeader("Access-Control-Allow-Headers",
"x-requested-with,origin,content-type,accept,X-XSRF-TOKEN");
response.setHeader("Access-Control-Allow-Credentials", "true"); // needed when withCredentials = true;
HttpServletRequest request = (HttpServletRequest) req;
if (!request.getMethod().equals("OPTIONS"))
chain.doFilter(req, res);
public void init(FilterConfig filterConfig)
public void destroy()
在application.properties
中设置applicationUrl
,像这样
applicationUrl: http://X.X.X.X
【讨论】:
如何从文件中调用服务器端服务,比如说file:///home/manish/test.html
,这里它只是一个存储在目录中的 html 文件。那么这里上面的方法也可以吗?
浏览器甚至不允许您从文件系统提供的页面执行 AJAX 请求。
我在我的手机上运行我的 android aap 所以在这种情况下如何处理来自手机的请求,因为那不是localhost://
在进行跨域请求之前,浏览器会询问服务器是否允许浏览器这样做。如果服务器拒绝,浏览器 会阻止它。如果您不从浏览器发送请求,那么没有什么可以阻止您执行跨源请求。顺便说一句,它不是跨域的,因为 android 应用程序不是网页,因此没有来源。以上是关于远程托管时 Spring REST api 不起作用的主要内容,如果未能解决你的问题,请参考以下文章
使用 Spring Data MongoDB 的 Rest API - 存储库方法不起作用
使用Spring Data MongoDB的Rest API - 存储库方法不起作用
请求 REST POST API 在 Postman 中工作,但在 Alamofire 中不起作用
如何使用 Spring 在单元测试中模拟远程 REST API?