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>  

猜你喜欢

转载自xhc66.iteye.com/blog/2300215