前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >nanohttpd:实现跨域(CORS)请求

nanohttpd:实现跨域(CORS)请求

作者头像
10km
发布2019-10-22 14:29:22
2.1K0
发布2019-10-22 14:29:22
举报
文章被收录于专栏:10km的专栏10km的专栏

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/10km/article/details/102568909

NanoHTTPD是一个轻量级的HTTP服务器,可以很方便地嵌入到Java程序中。所以在android平台上有广泛的使用。 NanoHTTPD默认是不支持访问跨域(CORS)请求的。如果希望自己的NanoHTTPD服务支持CORS,就要自己实现对CORS请求的响应。 关于什么是CORS,这个文档有非常详细、清晰、全面的阐述: 《HTTP访问控制(CORS)》,如果还不太清楚CORS机制的童鞋,建议先看这篇 文章补补课。

实现对跨域访问的支持的关键就是要响应跨请求,跨域请求的METHOD为OPTIONS,对收到的HTTP请求要先识别是否为跨域请求,如果是就发送正确的响应。下面是nanohttpd响应CORS请求的基本逻辑

代码语言:javascript
复制
    @Override
    public Response serve(IHTTPSession session) {
    	// 判断是否为跨域预请求
    	if(isPreflightRequest(session)){
    		// 如果是则发送CORS响应告诉浏览HTTP服务支持的METHOD及HEADERS和请求源
    		return responseCORS(session);
    	}
    	// 业务逻辑
    	.....
    	/////
    	return wrapResponse(session,responseAck(ack));
    }

下面是上述代码中调用的子方法的实现, 注意:因为nanohttp的headers中所有的key都是全小写,所以你会发现下面的代码,从headers获取header时,header的名字都是小写的。

代码语言:javascript
复制
	/**
	 * 判断是否为CORS 预检请求请求(Preflight)
	 * @param session
	 * @return
	 */
	private static boolean isPreflightRequest(IHTTPSession session) {
		Map<String, String> headers = session.getHeaders();
		return Method.OPTIONS.equals(session.getMethod()) 
				&& headers.containsKey("origin") 
				&& headers.containsKey("access-control-request-method") 
				&& headers.containsKey("access-control-request-headers");
	}
		/**
	 * 向响应包中添加CORS包头数据
	 * @param session
	 * @return
	 */
	private Response responseCORS(IHTTPSession session) {
		Response resp = wrapResponse(session,newFixedLengthResponse(""));
		Map<String, String> headers = session.getHeaders();
		resp.addHeader("Access-Control-Allow-Methods","POST,GET,OPTIONS");

		String requestHeaders = headers.get("access-control-request-headers");
		String allowHeaders = MoreObjects.firstNonNull(requestHeaders, "Content-Type");
		resp.addHeader("Access-Control-Allow-Headers", allowHeaders);
		//resp.addHeader("Access-Control-Max-Age", "86400");
		resp.addHeader("Access-Control-Max-Age", "0");
		return resp;
	}
	/**
	 * 封装响应包
	 * @param session http请求
	 * @param resp 响应包
	 * @return resp
	 */
	private Response wrapResponse(IHTTPSession session,Response resp) {
		if(null != resp){			
			Map<String, String> headers = session.getHeaders();
			resp.addHeader("Access-Control-Allow-Credentials", "true");
			// 如果请求头中包含'Origin',则响应头中'Access-Control-Allow-Origin'使用此值否则为'*'
			// nanohttd将所有请求头的名称强制转为了小写
			String origin = MoreObjects.firstNonNull(headers.get("origin", "*");
			resp.addHeader("Access-Control-Allow-Origin", origin);
			
			String  requestHeaders = headers.get("access-control-request-headers");
			if(requestHeaders != null){
				resp.addHeader("Access-Control-Allow-Headers", requestHeaders);
			}
		}
		return resp;
	}

完整的代码参见码云仓库代码: gu.dtalk.engine.DtalkHttpServer.java

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-10-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文档服务
文档服务(Document Service,DS)是腾讯云数据万象提供云上文档处理服务,支持多种类型的文件生成图片或 html 格式的预览,可以解决文档内容的页面展示问题,满足 PC、App 等多端的文档在线浏览需求。同时,本产品还提供文本隐私筛查能力,可以有效识别文本中的身份证号、银行卡号、手机号等敏感数据,满足数据可用性和隐私保护的各种要求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档