http協議可能是目前web遠程調用領域最常用的協議,一如之前的soap協議。作爲輕量級可靠傳輸協議,基於http協議的服務幾乎成了restful的代名詞,今天列舉幾個使用過程中http 相關的問題。
- 跨域
大家也最常遇到,解決辦法也有很多,譬如在網關服務中引入CorsFilter,指定或者放開所有的域名和header。
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
另一種解決辦法是調整代理服務器如nginx。
add_header 'Access-Control-Allow-Origin' '$http_origin';
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, PUT, POST, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type,*';
- 中文header
http協議不支持中文header!!!
所以想要在header中傳遞中文信息,需要轉碼,接收端再解碼。
Base64.encodeBase64String(origin.getBytes("utf-8"));
- header丟失
剛遇到的一個問題,request header中有個參數request_user_id, 認證服務攔截器發現request.getHeader取不到。一開始懷疑是apigateway的問題,查看了apigateway的代碼,發現只是普通的轉發,並沒有重新代理請求,所以不存在這個問題;將請求地址改爲ip重試(一開始請求的是域名地址),發現可以獲取header值,header參數的准入主要靠
corsFilter的 config.addAllowedHeader(""),現在配置的是,也就是除了中文外的所有參數都應該能傳遞纔對。
重新梳理服務鏈路,域名解析-nginx-apigateway-目標服務,鎖定到nginx頭上。nginx內部的設置,也是允許所有,但是nginx還有個限制,就是下劃線的參數,會被忽略(坑啊!)
調整nginx的http參數,打開下劃線參數,重啓,問題得到解決。
underscores_in_headers on;