【发布时间】:2017-12-20 20:40:08
【问题描述】:
我正在尝试设置我自己的 java http 服务器,以更好地了解 http 服务器以及网络底层发生的事情。我开发了一个非常简单的服务器,并且能够同时提供 html 页面和 JSON 格式的数据。然后我看到浏览器(我使用的是 chrome,但假设其他浏览器也一样)正在发送对 favicon.ico 的请求。我能够在我的服务器上识别该请求,因此我尝试提供一个随机图标,我下载并调整为 png 格式的 16x16 像素,因为这就是互联网所说的大小需要。这是我的代码,注意它不应该是任何专业的东西,只是对我的基本教育目的有用的东西:
[set up ServerSocket and listen]
public static String err_header = "HTTP/1.1 500 ERR\nAccess-Control-Allow-Origin: *";
public static String success_header = "HTTP/1.1 200 OK\nAccess-Control-Allow-Origin: *";
public static String end_header = "\r\n\r\n";
while(true){
try{
System.out.println("Listening for new connections");
clientSocket = server.accept();
System.out.println("Connection established");
InputStreamReader isr = new InputStreamReader(clientSocket.getInputStream());
BufferedReader reader = new BufferedReader(isr);
String getLine = reader.readLine();//first line of HTTP request
handleRequest(getLine,clientSocket);
}//end of try
catch(Exception e){
[error stuff]
}//end of catch
}//end of while
HandleRequest 方法:
public static void handleRequest(String getLine,Socket clientSocket) throws Exception{
if(getLine.substring(5,16).equals("favicon.ico")){
List<String> iconTag = new ArrayList<String>();
iconTag.add("\nContent-Type: image/png");
handleFileRequest("[file]",iconTag,clientSocket);
}//end of if
else{
handleFileRequest("[file]",clientSocket);
}//end of else
}//end of handleRequest
处理图片的文件请求:
public static void handleFileRequest(String fileName,List<String> headerTags,Socket clientSocket) throws Exception{
OutputStream out = clientSocket.getOutputStream();
BufferedReader read = new BufferedReader(new FileReader(fileName));
out.write(success_header.getBytes("UTF-8"));
Iterator<String> itr = headerTags.iterator();
while(itr.hasNext()){
out.write(itr.next().getBytes("UTF-8"));
}//end of while
out.write(end_header.getBytes("UTF-8"));
String readLine = "";
while((readLine = read.readLine())!=null){
out.write(readLine.getBytes("UTF-8"));
}//end of while
out.flush();
out.close();
}//end of handleFileRequest
它似乎可以工作,当服务器发送文件时,浏览器显示 200 OK 响应,但没有网站图标,当我将网络请求过滤为仅图像时,正在提供的页面请求了一个图像,但是favicon 请求未在此处列出(favicon 请求位于“其他”部分)。同样,当单击其他图像时,图像会显示在预览中,而 favicon 请求并非如此。截图:
同时这是另一张图片的样子,它在页面中显示得很好:
我也尝试包含 Content-Length 标头,但这似乎没有什么不同。我错过了什么明显的东西吗?
另外澄清一下,我知道我可以在实际的 html 页面中包含 favicon,目标不是这样做,而是要了解它是如何工作的。
【问题讨论】:
-
如果直接访问favicon的url,看到了吗?
-
没有 url,我通过 http 将其作为字节发送。
-
不确定你的意思。您可以在屏幕截图的 HTTP 请求标头中看到网站图标的 url。浏览器正在请求它。这就是浏览器通过发送 HTTP 请求来获取网站图标的方式。如果网站图标服务正确,那么如果您直接访问其网址,您应该能够看到它。
-
那么单独的http请求是怎么产生的?它向服务器发出请求以获取数据。我的服务器回复了适当的 HTTP 标头,后跟图标的二进制文件,而不是链接。适当的响应是否实际上只是 url,然后 chrome 会对该链接发出额外的 http 请求?
-
我去了那个截图中的网址。响应字段填充了适当的二进制文件,但图像未正确显示在浏览器中。