`

Ajax访问Restful API跨域解决方案

 
阅读更多

最近开发API接口时,用Ajax调用远程服务上API的接口时,出现以下错误 :

 

 

[java] view plain copy
 
  1. 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:代码如下:

 

[java] view plain copy
 
  1. package com.sumscope.cdh.api.interceptor;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintStream;  
  5. import java.io.PrintWriter;  
  6. import java.io.StringWriter;  
  7.   
  8. import javax.servlet.Filter;  
  9. import javax.servlet.FilterChain;  
  10. import javax.servlet.FilterConfig;  
  11. import javax.servlet.ServletException;  
  12. import javax.servlet.ServletRequest;  
  13. import javax.servlet.ServletResponse;  
  14. import javax.servlet.http.HttpServletResponse;  
  15.   
  16.   
  17. public class CrossFilter implements Filter {  
  18.     private static final boolean debug = true;  
  19.     private FilterConfig filterConfig = null;  
  20.       
  21.     public CrossFilter() {  
  22.         super();  
  23.     }  
  24.   
  25.     @Override  
  26.     public void init(FilterConfig filterConfig) throws ServletException {  
  27.         this.filterConfig = filterConfig;  
  28.         if (filterConfig != null) {  
  29.             if (debug) {                  
  30.                 log("CrossFilter:Initializing filter");  
  31.             }  
  32.         }  
  33.   
  34.     }  
  35.       
  36.      @Override  
  37.     public String toString() {  
  38.         if (filterConfig == null) {  
  39.             return ("CrossFilter()");  
  40.         }  
  41.         StringBuffer sb = new StringBuffer("CrossFilter(");  
  42.         sb.append(filterConfig);  
  43.         sb.append(")");  
  44.         return (sb.toString());  
  45.     }  
  46.   
  47.     @Override  
  48.     public void doFilter(ServletRequest request, ServletResponse response,  
  49.             FilterChain chain) throws IOException, ServletException {  
  50.         if (debug) {  
  51.             log("CrossFilter:doFilter()");  
  52.         }  
  53.   
  54.          if(response instanceof HttpServletResponse){  
  55.              HttpServletResponse alteredResponse = ((HttpServletResponse)response);  
  56.             // I need to find a way to make sure this only gets called on 200-300 http responses  
  57.             // TODO: see above comment  
  58.              addHeadersFor200Response(alteredResponse);  
  59.          }  
  60.          doBeforeProcessing(request, response);  
  61.   
  62.          Throwable problem = null;  
  63.          try {  
  64.              chain.doFilter(request, response);  
  65.          } catch (Throwable t) {  
  66.              // If an exception is thrown somewhere down the filter chain,  
  67.              // we still want to execute our after processing, and then  
  68.              // rethrow the problem after that.  
  69.              problem = t;  
  70.              t.printStackTrace();  
  71.          }  
  72.   
  73.          doAfterProcessing(request, response);  
  74.   
  75.          // If there was a problem, we want to rethrow it if it is  
  76.          // a known type, otherwise log it.  
  77.          if (problem != null) {  
  78.              if (problem instanceof ServletException) {  
  79.                  throw (ServletException) problem;  
  80.              }  
  81.              if (problem instanceof IOException) {  
  82.                  throw (IOException) problem;  
  83.              }  
  84.              sendProcessingError(problem, response);  
  85.          }  
  86.          
  87.   
  88.     }  
  89.   
  90.     @Override  
  91.     public void destroy() {  
  92.   
  93.     }  
  94.       
  95.     private void doBeforeProcessing(ServletRequest request, ServletResponse response)  
  96.             throws IOException, ServletException {  
  97.         if (debug) {  
  98.             log("CrossFilter:DoBeforeProcessing");  
  99.         }  
  100.   
  101.     }      
  102.   
  103.     private void doAfterProcessing(ServletRequest request, ServletResponse response)  
  104.             throws IOException, ServletException {  
  105.         if (debug) {  
  106.             log("CrossFilter:DoAfterProcessing");  
  107.         }  
  108.     }  
  109.       
  110.     private void addHeadersFor200Response(HttpServletResponse response){  
  111.         //TODO: externalize the Allow-Origin  
  112.         response.addHeader("Access-Control-Allow-Origin""*");  
  113.         response.addHeader("Access-Control-Allow-Methods""POST, GET, OPTIONS, PUT, DELETE, HEAD");  
  114.         response.addHeader("Access-Control-Allow-Headers""X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept");  
  115.         response.addHeader("Access-Control-Max-Age""1728000");  
  116.     }  
  117.       
  118.     private void sendProcessingError(Throwable t, ServletResponse response) {  
  119.         String stackTrace = getStackTrace(t);          
  120.   
  121.         if (stackTrace != null && !stackTrace.equals("")) {  
  122.             try {  
  123.                 response.setContentType("text/html");  
  124.                 PrintStream ps = new PrintStream(response.getOutputStream());  
  125.                 PrintWriter pw = new PrintWriter(ps);                  
  126.                 pw.print("<html>\n<head>\n<title>Error</title>\n</head>\n<body>\n"); //NOI18N  
  127.   
  128.                 // PENDING! Localize this for next official release  
  129.                 pw.print("<h1>The resource did not process correctly</h1>\n<pre>\n");                  
  130.                 pw.print(stackTrace);                  
  131.                 pw.print("</pre></body>\n</html>"); //NOI18N  
  132.                 pw.close();  
  133.                 ps.close();  
  134.                 response.getOutputStream().close();  
  135.             } catch (Exception ex) {  
  136.             }  
  137.         } else {  
  138.             try {  
  139.                 PrintStream ps = new PrintStream(response.getOutputStream());  
  140.                 t.printStackTrace(ps);  
  141.                 ps.close();  
  142.                 response.getOutputStream().close();  
  143.             } catch (Exception ex) {  
  144.             }  
  145.         }  
  146.     }  
  147.       
  148.     public static String getStackTrace(Throwable t) {  
  149.         String stackTrace = null;  
  150.         try {  
  151.             StringWriter sw = new StringWriter();  
  152.             PrintWriter pw = new PrintWriter(sw);  
  153.             t.printStackTrace(pw);  
  154.             pw.close();  
  155.             sw.close();  
  156.             stackTrace = sw.getBuffer().toString();  
  157.         } catch (Exception ex) {  
  158.         }  
  159.         return stackTrace;  
  160.     }  
  161.       
  162.     public void log(String msg) {  
  163.         filterConfig.getServletContext().log(msg);          
  164.     }  
  165.   
  166.   
  167. }  


在Web.xml配置域名访问过滤器

 

 

[html] view plain copy
 
  1.  <filter>     
  2.     <filter-name>crossFilter</filter-name>  
  3.    <filter-class>com.sumscope.cdh.api.interceptor.CrossFilter</filter-class>  
  4.  </filter>  
  5. <filter-mapping>  
  6.    <filter-name>crossFilter</filter-name>  
  7.    <url-pattern>/*</url-pattern>  
  8. </filter-mapping>  
分享到:
评论

相关推荐

    MVC+WebAPI跨域调用.rar

    2. **JSONP(JSON with Padding)**:JSONP是一种早期的跨域解决方案,适用于只支持GET请求的API。它通过动态创建`&lt;script&gt;`标签,利用其可以跨域加载脚本的特性来获取数据。但JSONP不支持POST等其他HTTP方法,且...

    JavaScript跨域调用基于JSON的RESTful API

    ### 跨域解决方案 在面对跨域问题时,开发者们总结出了几种主要的解决方法: #### 基于iframe实现跨域 这种方法要求两个页面必须属于一个基础域,使用相同的协议和端口。虽然这种方案有一定的局限性,比如对域名、...

    JavaScript跨域调用基于JSON的RESTful API_.docx

    CORS是一种更现代、更安全的跨域解决方案,它允许服务器通过设置特定的HTTP响应头,如`Access-Control-Allow-Origin`、`Access-Control-Allow-Methods`和`Access-Control-Allow-Headers`,明确允许哪些源的请求可以...

    支持Ajax跨域访问ASP.NET Web Api 2(Cors)的示例教程

    ###Ajax跨域访问和*** Web API 2(Cors) 在了解如何配置CORS之前,我们需要先了解几个关键点: 1. **同源策略**:浏览器安全策略的一部分,只有相同协议、域名和端口的请求才被视为同源。跨域请求通常不会被执行,...

    【ASP.NET编程知识】asp.net基于JWT的web api身份验证及跨域调用实践.docx

    本文介绍了基于JWT的Web API身份验证及跨域调用实践,展示了如何使用JWT技术来实现身份验证和授权,並討論了跨域调用的解决方案。 知识点: 1. ASP.NET Web API的基本概念和使用 2. Json Web Token(JWT)的基本...

    疯狂ajax 讲义 第三版 源码 01-05

    5. **AJAX与JSONP**:当涉及到跨域请求时,Ajax会遇到限制,此时JSONP(JSON with Padding)作为一种绕过同源策略的解决方案。这部分会介绍JSONP的工作原理,以及如何在实际代码中实现JSONP请求。 6. **Ajax库与...

    Ajax从入门到精通课件

    8. **跨域问题**:理解同源策略,学习JSONP和CORS等跨域解决方案。 9. **Ajax安全**:了解防止XSS和CSRF攻击的方法。 10. **Ajax库的使用**:如jQuery、axios等,简化Ajax操作。 11. **异步控制**:Promise和async/...

    Ajax光盘资料

    Ajax,全称Asynchronous ...通过Ajax光盘资料中的实例,我们可以逐步了解并掌握Ajax的各个方面,包括基本概念、工作流程、应用场景、常见问题及解决方案。不断实践和探索,将有助于我们成为更优秀的Web开发者。

    jquery跨域调用wcf

    2. **CORS**:CORS是现代浏览器支持的一种标准跨域解决方案。服务端需要在响应头中添加`Access-Control-Allow-Origin`字段,指定允许哪些源进行跨域请求。JQuery的$.ajax()函数可以通过设置xhrFields参数启用CORS。 ...

    Ajax高级程序设计

    9. **实践案例**:提供多个实际项目,展示Ajax在不同应用场景下的解决方案,如实时聊天、动态加载内容等。 书中可能还会讨论到现代Web开发中的相关话题,比如WebSockets用于实现即时通讯,以及Fetch API作为...

    ajax入门教程,包含ppt

    **六、跨域问题与解决方案** 由于同源策略限制,Ajax请求通常只能向同源发起。为解决跨域问题,可以采用JSONP、CORS(跨源资源共享)等方法。JSONP利用script标签的跨域特性,CORS则需要服务器设置特定的HTTP头部...

    陈洋小组ajax期末考试.zip

    了解CORS(Cross-Origin Resource Sharing)或其他跨域解决方案是解决这一问题的关键。 9. **错误处理**:处理Ajax请求的错误情况,如网络中断、服务器错误等,需要编写合适的错误处理代码。 10. **Promise和async...

    程序员突击:Ajax原理与系统开发

    1. **浏览器限制**:跨域请求(CORS)是Ajax的一个挑战,不过现代浏览器已提供解决方案。 2. **SEO问题**:由于Ajax加载的内容不在原始HTML中,搜索引擎可能无法抓取。 3. **不完整页面刷新**:用户无法通过刷新按钮...

    ajax有关的核心组件

    现代前端框架,如React、Vue和Angular,也提供了集成的解决方案,将Ajax请求与组件生命周期紧密结合。 7. **Ajax请求类型**:除了常见的GET和POST请求,XMLHttpRequest还支持PUT、DELETE等HTTP方法,这些在RESTful ...

    疯狂Ajax讲义3+Spring+hiberante

    《疯狂Ajax讲义3》是针对Web开发领域中Ajax技术的深入学习资料,结合Spring和Hibernate两大框架,为读者提供了一套完整的前后端交互及数据管理解决方案。这三者组合在一起,构成了现代Web应用程序开发的核心技术栈。...

    Ajax Hacks

    13. **移动设备支持**:探讨在移动设备上使用Ajax的挑战和解决方案,包括触摸事件和响应式设计。 14. **Ajax与RESTful API**:讲解如何使用Ajax与遵循REST(Representational State Transfer)原则的API进行交互。 ...

    第四阶段前后端分离作业

    6. **跨域问题与解决方案** 由于同源策略的限制,前端直接访问不同源的后端API会遇到跨域问题。解决方法包括设置CORS(跨源资源共享)头、JSONP(JSON with Padding)或使用代理服务器。 7. **安全性考虑** 分离...

    Ajax从入门到精通.rar

    1. **JSONP(JSON with Padding)**:跨域请求的一种解决方案,通过动态创建script标签实现。 2. **jQuery和Ajax**:jQuery简化了Ajax的使用,提供了一系列便捷的API。 3. **Ajax与RESTful API**:RESTful设计原则使...

    疯狂Ajax源码 11-12 章

    章节可能涵盖了CORS(Cross-Origin Resource Sharing)机制,以及JSONP(JSON with Padding)这种早期的跨域解决方案。 6. **错误处理**:讨论了如何在Ajax请求中有效地处理网络错误、服务器错误等异常情况,确保...

    Ajax与PHP基础教程.rar

    3. **跨域问题与解决方案**:探讨Ajax的同源策略限制及JSONP、CORS等跨域解决方案。 ### 第五章 - PHP与Ajax结合 1. **创建PHP API**:讲解如何构建RESTful API,供前端Ajax调用。 2. **处理Ajax响应**:讨论在PHP...

Global site tag (gtag.js) - Google Analytics