一般解决跨域问题可以通过 CORS、JSONP 和反向代理。下面分别介绍这三种方式。
1、CORS
如果接口需要携带 Cookie、Authorization 等凭证,后端不能把 Access-Control-Allow-Origin 直接设置为 *,必须返回具体允许的 Origin,并同时设置 Access-Control-Allow-Credentials: true。如果不需要凭证,才适合使用 * 简化配置。
以 Netty 为例,支持跨域请求需要配置返回头信息。
1 2 3 4 5 6 7 8 9 10 11
| FullHttpResponse response = null; String responseStr = result.toString() + "your-secret-salt"; response.headers().set("response", MD5Util.getMD5Code(responseStr, true)); response.headers().set(HttpHeaderNames.ACCESS_CONTROL_EXPOSE_HEADERS, "response"); response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json"); response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes()); response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, "*"); response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_HEADERS, "*"); response.headers().set("Access-Control-Allow-Headers", "PLATFORM,H5TOKEN,sign,UUID,RESOURCEPLATFORM,response"); response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE); ctx.writeAndFlush(response);
|
Spring 全局配置:
1 2 3 4 5 6 7 8 9 10
| @Configuration public class WebAppConfigurer implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://192.168.89.89") .allowedMethods("GET", "POST","DELETE") .allowCredentials(false).maxAge(3600); } }
|
Spring 单接口配置:
1 2 3 4 5 6
| @CrossOrigin(origins = "*", maxAge = 3600) @PostMapping("save") public ResponseEntity<Result> addNote(@RequestParam String noteName) { }
|
2、JSONP
AJAX 与 JSONP 的异同:
1、AJAX 和 JSONP 这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个 URL,然后处理服务器返回的数据。因此 jQuery 和 Ext 等框架都把 JSONP 作为 AJAX 的一种形式进行了封装。
2、但 AJAX 和 JSONP 本质上是不同的东西。AJAX 的核心是通过 XMLHttpRequest 获取非本页内容,而 JSONP 的核心是动态添加 script 标签。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>Untitled Page</title> <script type="text/javascript" src="jquery.min.js"></script> <script type="text/javascript"> jQuery(document).ready(function(){ $.ajax({ type: "get", async: false, url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998", dataType: "jsonp", jsonp: "callback", jsonpCallback:"flightHandler", success: function(json){ alert('您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。'); }, error: function(){ alert('fail'); } }); }); </script> </head> <body> </body> </html>
|
3、反向代理
配置 Nginx 就可以实现跨域,一般在生产环境采用这种方式。具体配置如下:
1 2 3 4 5 6 7
| location /ticketManagement/ { proxy_pass http://127.0.0.1:9001/; proxy_redirect off; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $http_host; }
|