我有一个Java服务器和一个JavaScript客户端,成功地使用服务器发送事件来发送更新。最近,我们被迫在使用内置在kubernetes中的NGINX作为服务器和客户端之间的代理与使用基于Kong的代理之间进行切换,该代理以不同的配置扩展NGINX。新的代理缓冲上交所通过它打破了协议,因为其他应用程序正在使用新的代理,我不允许关闭所有缓冲,这是以前的代理如何绕过这个问题。作为一种选择,我一直试图向SSE响应添加3个超文本传输协议标头,以触发NGINX关闭此特定endpoint的缓冲:
"Content-Type" : "text/event-stream"
"Cache-Control", "no-cache"
"X-Accel-Buffering", "no"
我已经能够相对容易地添加“缓存控制”和“X-加速缓冲”标头,但是我尝试了几种不同的方法来添加“内容类型”标头,没有任何效果。
下面是第一次尝试,请注意,“Content Type”标题的设置与RestServiceImpl中的其他两个标题相同,但从我的日志中添加了其他两个标题,而“Content Type”则没有。
@Api
@Path("/service")
public interface RestService {
@GET
@Path("/sseconnect")
@Produces(SseFeature.SERVER_SENT_EVENTS)
EventOutput listenToBroadcast(@Context HttpServletResponse response);
}
@Component
public class RestServiceImpl implements RestService {
@Autowired
private Broadcaster broadcaster;
public RestServiceImpl() {
}
@Override
public EventOutput listenToBroadcast(HttpServletResponse response) {
response.addHeader("Content-Type", "text/event-stream");
response.addHeader("Cache-Control", "no-cache");
response.addHeader("X-Accel-Buffering", "no");
return broadcaster.add();
}
}
public class Broadcaster extends SseBroadcaster {
private final OutboundEvent.Builder eventBuilder =
new OutboundEvent.Builder();
public EventOutput add() {
final EventOutput eventOutput = new EventOutput();
super.add(eventOutput);
return eventOutput;
}
public void sendEvents(Events events, String name) {
final OutboundEvent outboundEvent = eventBuilder.name(name)
.mediaType(MediaType.APPLICATION_JSON_TYPE)
.data(Events.class, events).build();
super.broadcast(outboundEvent);
}
}
在第二次尝试中,我尝试修改“Content Type”标题的添加方式,如下所示:
@Override
public EventOutput listenToBroadcast(HttpServletResponse response) {
response.setContentType("text/event-stream");
response.addHeader("Cache-Control", "no-cache");
response.addHeader("X-Accell-Buffering", no);
return broadcaster.add();
}
这具有相同的效果,添加了“缓存控制”和“X-Accell-Bufferig”,但没有添加“内容类型”。
对于第三次尝试,我将HttpServletResponse替换为ContainerResponse
@Override
public EventOutput listenToBroadcast(ContainerResponse containerResponse)
{
final MultivaluedMap<String, Object> headers =
containerResponse.getHeaders();
headers.add("Content-Type", "text/event-stream");
headers.add("Cache-Control", "no-cache");
headers.add("X-Accel-Buffering", "no");
return broadcaster.add();
}
这个解决方案破坏了endpoint,最后给了我一个406错误,所以我不能肯定地说它不起作用。可能是一个糟糕的实现,但我没有看到任何东西。
在第四次尝试中,我尝试使用ContainerResponseFilter添加标题。
@Provider
@PreMatching
public class SseResponseFilter implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext)
throws IOException {
final MultivaluedMap<String, Object> headers =
responseContext.getHeaders();
final List<Object> contentTypeValues = new ArrayList<Object>();
contentTypeValues.add("text/event-stream");
headers.put("Content-Type", contentTypeValues);
final List<Object> cacheControlValues = new ArrayList<Object>();
cacheControlValues.add("no-cache");
headers.put("Cache-Control", cacheControlValues);
final List<Object> xAccelBufferingValues =
new ArrayList<Object>();
xAccelBufferingValues.add("no");
headers.put("X-Accel-Buffering", xAccelBufferingValues);
}
}
此尝试将“缓存控制”和“X-Accel-Buffering”头添加到应用程序中的每个endpoint,但没有在任何位置添加“内容类型”。注意,这些其他api中的一些正在返回允许设置“内容类型”的响应对象,而这些剩余endpoint正在为每个特定endpoint正确设置“内容类型”头。SSE库返回EventOutput,很遗憾,它不允许我像Response一样设置内容类型头。
在第五次尝试中,我将ContainerResponseFilter替换为WriterInterceptor
@Provider
public class SseWriterInterceptor implements WriterInterceptor {
@Override
public void arroundWriteTo(WriterInterceptorContext context)
throws IOException, WebApplicationException {
final MultivaluedMap<String, Object> headers =
context.getHeaders();
final List<Object> contentTypeValues = new ArrayList<Object>();
contentTypeValues.add("text/event-stream");
headers.put("Content-Type", contentTypeValues);
final List<Object> cacheControlValues = new ArrayList<Object>();
cacheControlValues.add("no-cache");
headers.put("Cache-Control", cacheControlValues);
final List<Object> xAccelBufferingValues =
new ArrayList<Object>();
xAccelBufferingValues.add("no");
headers.put("X-Accel-Buffering", xAccelBufferingValues);
}
}
此解决方案与之前的解决方案类似,在之前的解决方案中,它向应用程序中的所有endpoint添加了“缓存控制”和“X-加速缓冲”,但再次放弃了“内容类型”。
总而言之,我似乎无法找出是什么阻止我成功地将“Content-Type”头添加到SSEendpoint。
这个问题类似于:Jersey为什么要吞下我的“Content Encoding”头?然而,将“Content Type”添加到响应对象的给定解决方案不起作用,因为我使用的是SSE,它返回的EventOutput对象无法添加“Content Type”头。
事实证明,泽西并不是未设置“内容类型”标题的罪魁祸首。该应用程序是作为连续部署环境的一部分构建的,该环境为日志记录和安全扫描等事项添加了大量过滤器。其中一个过滤器是防止在使用SSE库时填充“Content Type”标题。
在本地机器上运行应用程序,而不是在基于kubernetes的开发环境中运行应用程序,并且看到“Content-Type”头正确地填充了本地的第一个解决方案后,我能够确定这是原因。
我无法在HttpClient上设置内容类型。我接着问了一个问题:如何为HttpClient请求设置Content-Type头?但还是没有运气。 所以我怎么能强迫它,这样它就真的添加了它呢?提前道谢。
以下代码使用CORS协议完美地发送请求并接收响应。我想将内容类型标头更改为“应用程序/json”而不是“应用程序/x-www-form-urlencoded”。但是,当我将内容类型替换为“应用程序/json”时,请求失败。当我在浏览器中检查请求时,我可以看到内容类型标头已被删除而不是更改。 来自以上代码的请求 当“应用程序/x-web-form-urlencoded”被替换为“应用程序/json”
我试图配置标题'Content-Type'从空手道,我不能这样做。我尝试了*configure header={'Content-Type':'application/json;charset=utf-8'}和*header Content-Type='application/json;charset=utf-8'。但是在我打的post电话中,我总是得到content-type:text/plai
我使用GraphQL. Client Nuget包调用需要Content-Type头的Graphql API。以下是我正在做的 设置GraphQL选项。注:我已经设置了选项。媒体类型 初始化客户端和授权标头 GraphQL查询 调用API并检索响应结果 但是,我收到错误的请求,错误为“{”errors:[{”message:“必须提供查询字符串。”}]}” 我做错了什么?如何正确设置内容类型标题。
我正在尝试生成一个带有授权标头的HTTP请求: 但此代码生成的请求不包含授权头: Cache-Control:无缓存 access-control-request-method: 来源:http://localhost:3021 接受语言:en-US,en;q=0.8,he;q=0.6 我做错了什么?
问题内容: 为了避免未知,我一直试图避免使用大多数HTTP协议的属性。 但是,我对自己说,今天我将面对恐惧,开始有目的地使用标题。我一直在尝试将数据发送到浏览器并立即使用。例如,如果我有一个处于就绪状态4的Ajax处理程序函数,如下所示: 并且我在PHP代码中设置了content-type标头: 当清楚地告诉浏览器传入数据为时,为什么不能直接从处理程序函数访问该属性? 问题答案: 该头只是作为您的