首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >清漆升级后HTML/JSON接受不工作

清漆升级后HTML/JSON接受不工作
EN

Stack Overflow用户
提问于 2021-11-18 18:30:59
回答 1查看 27关注 0票数 0

升级后的清漆4 ->清漆-6.2.1“接受”-Request不响应预期。

如果我使用"Accept: application/json“发出第一个请求,它将返回HTML,在第二个请求时,它将继续工作。

使用Varnish3,下面的代码片段使其工作--但与varnish6无关

代码语言:javascript
复制
sub vcl_backend_response {
    # Called after the response headers has been successfully retrieved from the backend.

    if (!beresp.http.Vary) { # no Vary at all
        set beresp.http.Vary = "Accept";
    } elseif (beresp.http.Vary !~ "Accept") { # add to existing Vary
        set beresp.http.Vary = beresp.http.Vary + ", Accept";
    }
}

sub normalize {
    # Normalize the header, remove the port (in case you're testing this on various TCP ports)
    set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");
    # Remove the proxy header (see https://httpoxy.org/#mitigate-varnish)
    unset req.http.proxy;
    # Normalize the query arguments
    set req.url = std.querysort(req.url);

    if (req.http.Accept) {
        if (req.http.Accept ~ "application/json") {
            set req.http.Accept = "application/json";
        } else {
            set req.http.Accept = "text/html";
        }
    }
}

它与Varnish 3: Accept JSON returns HTML不一样,但非常相似:

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-24 07:53:54

我已经测试过您的VCL代码,它运行得很好。使sub normalize工作所需的惟一添加是以下内容:

代码语言:javascript
复制
sub vcl_recv {
    call normalize;
}

PHP测试脚本

我编写了一个小测试脚本来复制原点的变异行为。下面是代码:

代码语言:javascript
复制
<?php
header('Cache-Control: public, s-maxage=3600');
$timestamp = date('Y-m-d H:i:s');
if(isset($_SERVER['HTTP_ACCEPT']) && preg_match('/application\/json/',$_SERVER['HTTP_ACCEPT'])) {
    header('Content-Type: application/json');
    $obj = new stdClass;
    $obj->timestamp = $timestamp;
    echo json_encode($obj);
} else {
    echo $timestamp;
}

如果在application/json头中找到Accept,它将返回以下输出:

代码语言:javascript
复制
{"timestamp":"2021-11-24 07:38:35"}

否则,它将返回以下普通输出:

代码语言:javascript
复制
2021-11-24 07:38:35

VCL

下面是我为此使用的VCL:

代码语言:javascript
复制
vcl 4.1;

import std;

backend default {
    .host = "localhost";
    .port = "8080";
}

sub vcl_backend_response {
    # Called after the response headers has been successfully retrieved from the backend.

    if (!beresp.http.Vary) { # no Vary at all
        set beresp.http.Vary = "Accept";
    } elseif (beresp.http.Vary !~ "Accept") { # add to existing Vary
        set beresp.http.Vary = beresp.http.Vary + ", Accept";
    }
}

sub normalize {
    # Normalize the header, remove the port (in case you're testing this on various TCP ports)
    set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");
    # Remove the proxy header (see https://httpoxy.org/#mitigate-varnish)
    unset req.http.proxy;
    # Normalize the query arguments
    set req.url = std.querysort(req.url);

    if (req.http.Accept) {
        if (req.http.Accept ~ "application/json") {
            set req.http.Accept = "application/json";
        } else {
            set req.http.Accept = "text/html";
        }
    }
}

sub vcl_recv {
    call normalize;
}

如果这不适用于您,如何调试?

您可以运行以下varnishlog命令来查看发生了什么:

代码语言:javascript
复制
varnishlog -g request -I ReqHeader:Accept -i requrl -i berequrl -I RespHeader:Vary -I BereqHeader:Accept -I BerespHeader:Vary -i vcl_call -i vcl_return

以下是HTML上现金丢失的一些示例varnishlog输出:

代码语言:javascript
复制
*   << Request  >> 34
-   ReqURL         /test
-   ReqHeader      Accept: */*
-   VCL_call       RECV
-   ReqURL         /test
-   ReqHeader      Accept: text/html
-   VCL_return     hash
-   VCL_call       HASH
-   VCL_return     lookup
-   VCL_call       MISS
-   VCL_return     fetch
-   RespHeader     Vary: Accept
-   VCL_call       DELIVER
-   VCL_return     deliver
**  << BeReq    >> 35
--  BereqURL       /test
--  BereqHeader    Accept: text/html
--  BereqHeader    Accept-Encoding: gzip
--  VCL_call       BACKEND_FETCH
--  VCL_return     fetch
--  VCL_call       BACKEND_RESPONSE
--  BerespHeader   Vary: Accept
--  VCL_return     deliver

下面是针对普通HTML的缓存命中的情况:

代码语言:javascript
复制
*   << Request  >> 32800
-   ReqURL         /test
-   ReqHeader      Accept: */*
-   VCL_call       RECV
-   ReqURL         /test
-   ReqHeader      Accept: text/html
-   VCL_return     hash
-   VCL_call       HASH
-   VCL_return     lookup
-   VCL_call       HIT
-   VCL_return     deliver
-   RespHeader     Vary: Accept
-   VCL_call       DELIVER
-   VCL_return     deliver

即使HTML版本仍在缓存中,Accept: application/json也会导致缓存丢失:

代码语言:javascript
复制
*   << Request  >> 32802
-   ReqURL         /test
-   ReqHeader      Accept:application/json
-   VCL_call       RECV
-   ReqURL         /test
-   ReqHeader      Accept: application/json
-   VCL_return     hash
-   VCL_call       HASH
-   VCL_return     lookup
-   VCL_call       MISS
-   VCL_return     fetch
-   RespHeader     Vary: Accept
-   VCL_call       DELIVER
-   VCL_return     deliver
**  << BeReq    >> 32803
--  BereqURL       /test
--  BereqHeader    Accept: application/json
--  BereqHeader    Accept-Encoding: gzip
--  VCL_call       BACKEND_FETCH
--  VCL_return     fetch
--  VCL_call       BACKEND_RESPONSE
--  BerespHeader   Vary: Accept
--  VCL_return     deliver

下一次,这将对JSON输出造成影响:

代码语言:javascript
复制
*   << Request  >> 32805
-   ReqURL         /test
-   ReqHeader      Accept:application/json
-   VCL_call       RECV
-   ReqURL         /test
-   ReqHeader      Accept: application/json
-   VCL_return     hash
-   VCL_call       HASH
-   VCL_return     lookup
-   VCL_call       HIT
-   VCL_return     deliver
-   RespHeader     Vary: Accept
-   VCL_call       DELIVER
-   VCL_return     deliver
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70024971

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档