最近开发API接口时,用Ajax调用远程服务上API的接口时,出现以下错误 :
- XMLHttpRequest cannot load http://192.168.1.101:8080/CDHAPI/bond/quote/minutely/1m/112188.SZ. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
产生此种问题是由于Ajax跨域限制而引起的问题。Access-Control-Allow-Origin是HTML5中定义的一种服务器端返回Response header,用来解决资源(比如字体)的跨域权限问题。它定义了该资源允许被哪个域引用,或者被所有域引用。
根据这个思路,在服务端返回时在响应体的添加Header,设置Access-Control-Allow-Origin允许可访问的域。具体工作如下:
(1)写一个过滤器,在Reponse中Header中设置Access-Control-Allow-Origin:代码如下:
- package com.sumscope.cdh.api.interceptor;
- import java.io.IOException;
- import java.io.PrintStream;
- import java.io.PrintWriter;
- import java.io.StringWriter;
- import javax.servlet.Filter;
- import javax.servlet.FilterChain;
- import javax.servlet.FilterConfig;
- import javax.servlet.ServletException;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
- import javax.servlet.http.HttpServletResponse;
- public class CrossFilter implements Filter {
- private static final boolean debug = true;
- private FilterConfig filterConfig = null;
- public CrossFilter() {
- super();
- }
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- this.filterConfig = filterConfig;
- if (filterConfig != null) {
- if (debug) {
- log("CrossFilter:Initializing filter");
- }
- }
- }
- @Override
- public String toString() {
- if (filterConfig == null) {
- return ("CrossFilter()");
- }
- StringBuffer sb = new StringBuffer("CrossFilter(");
- sb.append(filterConfig);
- sb.append(")");
- return (sb.toString());
- }
- @Override
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain chain) throws IOException, ServletException {
- if (debug) {
- log("CrossFilter:doFilter()");
- }
- if(response instanceof HttpServletResponse){
- HttpServletResponse alteredResponse = ((HttpServletResponse)response);
- // I need to find a way to make sure this only gets called on 200-300 http responses
- // TODO: see above comment
- addHeadersFor200Response(alteredResponse);
- }
- doBeforeProcessing(request, response);
- Throwable problem = null;
- try {
- chain.doFilter(request, response);
- } catch (Throwable t) {
- // If an exception is thrown somewhere down the filter chain,
- // we still want to execute our after processing, and then
- // rethrow the problem after that.
- problem = t;
- t.printStackTrace();
- }
- doAfterProcessing(request, response);
- // If there was a problem, we want to rethrow it if it is
- // a known type, otherwise log it.
- if (problem != null) {
- if (problem instanceof ServletException) {
- throw (ServletException) problem;
- }
- if (problem instanceof IOException) {
- throw (IOException) problem;
- }
- sendProcessingError(problem, response);
- }
- }
- @Override
- public void destroy() {
- }
- private void doBeforeProcessing(ServletRequest request, ServletResponse response)
- throws IOException, ServletException {
- if (debug) {
- log("CrossFilter:DoBeforeProcessing");
- }
- }
- private void doAfterProcessing(ServletRequest request, ServletResponse response)
- throws IOException, ServletException {
- if (debug) {
- log("CrossFilter:DoAfterProcessing");
- }
- }
- private void addHeadersFor200Response(HttpServletResponse response){
- //TODO: externalize the Allow-Origin
- response.addHeader("Access-Control-Allow-Origin", "*");
- response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, HEAD");
- response.addHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept");
- response.addHeader("Access-Control-Max-Age", "1728000");
- }
- private void sendProcessingError(Throwable t, ServletResponse response) {
- String stackTrace = getStackTrace(t);
- if (stackTrace != null && !stackTrace.equals("")) {
- try {
- response.setContentType("text/html");
- PrintStream ps = new PrintStream(response.getOutputStream());
- PrintWriter pw = new PrintWriter(ps);
- pw.print("<html>\n<head>\n<title>Error</title>\n</head>\n<body>\n"); //NOI18N
- // PENDING! Localize this for next official release
- pw.print("<h1>The resource did not process correctly</h1>\n<pre>\n");
- pw.print(stackTrace);
- pw.print("</pre></body>\n</html>"); //NOI18N
- pw.close();
- ps.close();
- response.getOutputStream().close();
- } catch (Exception ex) {
- }
- } else {
- try {
- PrintStream ps = new PrintStream(response.getOutputStream());
- t.printStackTrace(ps);
- ps.close();
- response.getOutputStream().close();
- } catch (Exception ex) {
- }
- }
- }
- public static String getStackTrace(Throwable t) {
- String stackTrace = null;
- try {
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- t.printStackTrace(pw);
- pw.close();
- sw.close();
- stackTrace = sw.getBuffer().toString();
- } catch (Exception ex) {
- }
- return stackTrace;
- }
- public void log(String msg) {
- filterConfig.getServletContext().log(msg);
- }
- }
在Web.xml配置域名访问过滤器
- <filter>
- <filter-name>crossFilter</filter-name>
- <filter-class>com.sumscope.cdh.api.interceptor.CrossFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>crossFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
相关推荐
2. **JSONP(JSON with Padding)**:JSONP是一种早期的跨域解决方案,适用于只支持GET请求的API。它通过动态创建`<script>`标签,利用其可以跨域加载脚本的特性来获取数据。但JSONP不支持POST等其他HTTP方法,且...
### 跨域解决方案 在面对跨域问题时,开发者们总结出了几种主要的解决方法: #### 基于iframe实现跨域 这种方法要求两个页面必须属于一个基础域,使用相同的协议和端口。虽然这种方案有一定的局限性,比如对域名、...
CORS是一种更现代、更安全的跨域解决方案,它允许服务器通过设置特定的HTTP响应头,如`Access-Control-Allow-Origin`、`Access-Control-Allow-Methods`和`Access-Control-Allow-Headers`,明确允许哪些源的请求可以...
###Ajax跨域访问和*** Web API 2(Cors) 在了解如何配置CORS之前,我们需要先了解几个关键点: 1. **同源策略**:浏览器安全策略的一部分,只有相同协议、域名和端口的请求才被视为同源。跨域请求通常不会被执行,...
本文介绍了基于JWT的Web API身份验证及跨域调用实践,展示了如何使用JWT技术来实现身份验证和授权,並討論了跨域调用的解决方案。 知识点: 1. ASP.NET Web API的基本概念和使用 2. Json Web Token(JWT)的基本...
5. **AJAX与JSONP**:当涉及到跨域请求时,Ajax会遇到限制,此时JSONP(JSON with Padding)作为一种绕过同源策略的解决方案。这部分会介绍JSONP的工作原理,以及如何在实际代码中实现JSONP请求。 6. **Ajax库与...
8. **跨域问题**:理解同源策略,学习JSONP和CORS等跨域解决方案。 9. **Ajax安全**:了解防止XSS和CSRF攻击的方法。 10. **Ajax库的使用**:如jQuery、axios等,简化Ajax操作。 11. **异步控制**:Promise和async/...
Ajax,全称Asynchronous ...通过Ajax光盘资料中的实例,我们可以逐步了解并掌握Ajax的各个方面,包括基本概念、工作流程、应用场景、常见问题及解决方案。不断实践和探索,将有助于我们成为更优秀的Web开发者。
2. **CORS**:CORS是现代浏览器支持的一种标准跨域解决方案。服务端需要在响应头中添加`Access-Control-Allow-Origin`字段,指定允许哪些源进行跨域请求。JQuery的$.ajax()函数可以通过设置xhrFields参数启用CORS。 ...
9. **实践案例**:提供多个实际项目,展示Ajax在不同应用场景下的解决方案,如实时聊天、动态加载内容等。 书中可能还会讨论到现代Web开发中的相关话题,比如WebSockets用于实现即时通讯,以及Fetch API作为...
**六、跨域问题与解决方案** 由于同源策略限制,Ajax请求通常只能向同源发起。为解决跨域问题,可以采用JSONP、CORS(跨源资源共享)等方法。JSONP利用script标签的跨域特性,CORS则需要服务器设置特定的HTTP头部...
了解CORS(Cross-Origin Resource Sharing)或其他跨域解决方案是解决这一问题的关键。 9. **错误处理**:处理Ajax请求的错误情况,如网络中断、服务器错误等,需要编写合适的错误处理代码。 10. **Promise和async...
1. **浏览器限制**:跨域请求(CORS)是Ajax的一个挑战,不过现代浏览器已提供解决方案。 2. **SEO问题**:由于Ajax加载的内容不在原始HTML中,搜索引擎可能无法抓取。 3. **不完整页面刷新**:用户无法通过刷新按钮...
现代前端框架,如React、Vue和Angular,也提供了集成的解决方案,将Ajax请求与组件生命周期紧密结合。 7. **Ajax请求类型**:除了常见的GET和POST请求,XMLHttpRequest还支持PUT、DELETE等HTTP方法,这些在RESTful ...
《疯狂Ajax讲义3》是针对Web开发领域中Ajax技术的深入学习资料,结合Spring和Hibernate两大框架,为读者提供了一套完整的前后端交互及数据管理解决方案。这三者组合在一起,构成了现代Web应用程序开发的核心技术栈。...
13. **移动设备支持**:探讨在移动设备上使用Ajax的挑战和解决方案,包括触摸事件和响应式设计。 14. **Ajax与RESTful API**:讲解如何使用Ajax与遵循REST(Representational State Transfer)原则的API进行交互。 ...
6. **跨域问题与解决方案** 由于同源策略的限制,前端直接访问不同源的后端API会遇到跨域问题。解决方法包括设置CORS(跨源资源共享)头、JSONP(JSON with Padding)或使用代理服务器。 7. **安全性考虑** 分离...
1. **JSONP(JSON with Padding)**:跨域请求的一种解决方案,通过动态创建script标签实现。 2. **jQuery和Ajax**:jQuery简化了Ajax的使用,提供了一系列便捷的API。 3. **Ajax与RESTful API**:RESTful设计原则使...
章节可能涵盖了CORS(Cross-Origin Resource Sharing)机制,以及JSONP(JSON with Padding)这种早期的跨域解决方案。 6. **错误处理**:讨论了如何在Ajax请求中有效地处理网络错误、服务器错误等异常情况,确保...
3. **跨域问题与解决方案**:探讨Ajax的同源策略限制及JSONP、CORS等跨域解决方案。 ### 第五章 - PHP与Ajax结合 1. **创建PHP API**:讲解如何构建RESTful API,供前端Ajax调用。 2. **处理Ajax响应**:讨论在PHP...