You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中OkHttp3获取图片文件而非HTML响应的技术求助

问题分析

你遇到的是免费主机(infinityfree)的人机验证/防盗链机制:首次请求会返回一段JS脚本,用于设置_test Cookie并自动重定向到带i=1参数的真实下载地址。浏览器会自动执行JS完成Cookie设置和跳转,但OkHttp不会解析执行JS,因此直接请求会拿到这段HTML而非文件数据。同时你的Java代码用string()读取二进制文件的方式也错误,会破坏文件内容。


解决方案

一、修改OkHttp代码(核心解决步骤)

需要手动解析首次响应中的Cookie和重定向URL,带上Cookie发起第二次请求,同时用正确方式读取二进制文件:

OkHttpClient client = new OkHttpClient.Builder()
        .followRedirects(true)
        .build();

// 1. 发起首次请求,获取验证Cookie和重定向地址
String initialUrl = "http://www.webweb.infinityfreeapp.com/lichi/download.php?path=Add.jpg";
Request initialReq = new Request.Builder().url(initialUrl).get().build();
Response initialResp = client.newCall(initialReq).execute();

if (initialResp.isSuccessful()) {
    String htmlContent = initialResp.body().string();
    
    // 解析_test Cookie值
    String testCookie = null;
    Pattern cookiePattern = Pattern.compile("_test=([a-f0-9]+)");
    Matcher cookieMatcher = cookiePattern.matcher(htmlContent);
    if (cookieMatcher.find()) {
        testCookie = cookieMatcher.group(1);
    }

    // 解析重定向URL
    String redirectUrl = null;
    Pattern redirectPattern = Pattern.compile("document\\.location\\.href=\"(.*?)\"");
    Matcher redirectMatcher = redirectPattern.matcher(htmlContent);
    if (redirectMatcher.find()) {
        redirectUrl = redirectMatcher.group(1);
    }

    // 2. 带上Cookie发起真实下载请求
    if (testCookie != null && redirectUrl != null) {
        Request downloadReq = new Request.Builder()
                .url(redirectUrl)
                .addHeader("Cookie", "_test=" + testCookie)
                .get()
                .build();
        Response downloadResp = client.newCall(downloadReq).execute();
        
        if (downloadResp.isSuccessful()) {
            // 用bytes()读取二进制文件,不要用string()
            byte[] fileData = downloadResp.body().bytes();
            // 这里添加文件保存逻辑,比如写入本地存储
            Log.d(LOG_TAG, "文件下载成功,大小:" + fileData.length);
        }
    }
}

二、优化PHP代码(辅助规范响应)

你的PHP代码存在MIME类型错误、文件路径不合理的问题,优化后能让响应更规范,避免潜在问题:

if(isset($_GET['path']))
{
    $fileName = $_GET['path'];
    $localFilePath = __DIR__ . '/' . $fileName; // 使用本地路径代替远程URL,避免allow_url_fopen限制
    
    // 验证文件存在性
    if(!file_exists($localFilePath)){
        http_response_code(404);
        die("文件不存在");
    }

    // 根据文件后缀设置正确的MIME类型
    $fileExt = pathinfo($fileName, PATHINFO_EXTENSION);
    $mimeTypes = [
        'jpg' => 'image/jpeg',
        'jpeg' => 'image/jpeg',
        'png' => 'image/png',
        'pdf' => 'application/pdf'
    ];
    $contentType = isset($mimeTypes[$fileExt]) ? $mimeTypes[$fileExt] : 'application/octet-stream';

    // 输出下载响应头
    header("Content-disposition: attachment; filename=" . basename($fileName)); 
    header("Content-Type: $contentType"); 
    header("Content-Transfer-Encoding: binary");
    header("Pragma: no-cache"); 
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0, public"); 
    header("Expires: 0"); 
    header("Content-Length: " . filesize($localFilePath)); // 本地文件可正常获取大小

    readfile($localFilePath); 
    die();
}

内容的提问来源于stack exchange,提问作者Hitlar India

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 18:45:36