9

이 문제는 백본 또는 JavaScript와 관련이 없지만 일부 백본 코드를 컨텍스트로 포함시켜야합니다.뒤로 버튼을 클릭하면 캐시에서 직접 응답을받습니다.

는 관련 코드

나는 contactId라는 매개 변수를 경로와 client-side Backbone router 있습니다. 그것은이 유사하게 나타납니다

Backbone.Router.extend({ 

    routes: { 
    "jobs/new?contact_id=:contactId": "newForContact" 
    }, 

    // Fetch the contact and initialize a new job model which 
    // is associated with that contact. 
    newForContact: function(contactId) { 
    var contact = new Contact(id: contactId); 
    contact.fetch({ 
     success: _.bind(function(model, resp) { 
     var job = new Job(contact: contact); 
     this.new(job); 
     } 
    }, this)); 
    }, 

    // Show the JobView for the given job. 
    new: function(jobModel) { 
    view = new JobView(job: jobModel); 
    $('body').append(view.render().el); 
    } 
}; 

는 지금은 pushState이 켜져으로이 설정을 사용하도록 노력하고있어.

newForContact 경로를 트리거하는 경로를 누르면 모든 것이 예상대로 작동합니다. 그러나이 시점에서 브라우저의 뒤로 버튼을 누르면 브라우저의 캐시에서 곧바로 contact.fetch() 메서드의 JSON 응답을받습니다. 서버에 요청이 보내지지 않습니다.

fetch JSON response

앱 로그

당신은 레일 응용 프로그램 로그에서 볼 수 있습니다. 이 부분에서는 newForContact을 트리거하는 경로를 방문합니다.

Started GET "/jobs/new?contact%5Bid%5D=1&contact%5Btype%5D=Customer" for 127.0.0.1 at 2012-10-31 22:41:48 +0000 
Processing by JobsController#new as HTML 
    Parameters: {"contact"=>{"id"=>"1", "type"=>"Customer"}} 
    User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]] 
    Business Load (0.3ms) SELECT "businesses".* FROM "businesses" WHERE "businesses"."id" IN (1) 
    Rendered shared/_search_form.html.erb (0.3ms) 
    Job Load (0.4ms) SELECT "jobs".* FROM "jobs" WHERE "jobs"."business_id" = 1 ORDER BY created_at desc 
    Rendered jobs/_list.html.erb (1.5ms) 
    Rendered jobs/index.html.erb within layouts/application (4.1ms) 
    Rendered layouts/_head_content.html.erb (0.7ms) 
    Rendered layouts/_flash.html.erb (0.0ms) 
Cache read: views/jobs/main_nav/d6a805d9b6f285e424f207add4f35595 
Read fragment views/jobs/main_nav/d6a805d9b6f285e424f207add4f35595 (0.4ms) 
    Rendered layouts/_nav.html.erb (0.6ms) 
    Rendered layouts/_header.html.erb (0.7ms) 
Completed 200 OK in 12ms (Views: 8.0ms | ActiveRecord: 1.0ms) 
Cache read: http://print.dev/customers/1? 

이 시점에서 JSON 요청으로 연락처를 가져 오는 것을 확인할 수 있습니다.

Started GET "/customers/1" for 127.0.0.1 at 2012-10-31 22:41:48 +0000 
Processing by CustomersController#show as JSON 
    Parameters: {"id"=>"1"} 
    User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]] 
    Business Load (0.4ms) SELECT "businesses".* FROM "businesses" WHERE "businesses"."id" IN (1) 
    Customer Load (0.2ms) SELECT "customers".* FROM "customers" WHERE "customers"."business_id" = 1 AND "customers"."id" = $1 LIMIT 1 [["id", "1"]] 
    CustomerEmployee Load (0.3ms) SELECT "customer_employees".* FROM "customer_employees" WHERE "customer_employees"."employer_id" IN (1) 
    Job Load (0.4ms) SELECT "jobs".* FROM "jobs" WHERE "jobs"."contact_type" = 'Customer' AND "jobs"."contact_id" IN (1) 
    Invoice Load (0.3ms) SELECT "invoices".* FROM "invoices" WHERE "invoices"."client_id" IN (1) 
    Job Load (0.5ms) SELECT "jobs".* FROM "jobs" WHERE "jobs"."contact_id" = 1 AND "jobs"."contact_type" = 'Customer' AND "jobs"."state" = 'finished' AND "jobs"."invoice_id" IS NULL 
    Rendered customers/show.json.rabl (2.8ms) 
Completed 200 OK in 67ms (Views: 3.2ms | ActiveRecord: 2.5ms) 

이 시점에서 브라우저의 뒤로 버튼을 누르면 서버에 새로운 요청이 기록되지 않습니다.

레일 환경

이것은 단지 내 준비 서버 (Heroku),하지 개발에 발생합니다. 레일 구성에서 캐싱이 켜져있는 스테이징 환경에서 Pow으로 앱을 실행하여 로컬로 다시 생성 할 수 있습니다.

config.action_controller.perform_caching = true 

캐시가 켜져 있어도 개발 환경에서 버그를 다시 만들 수 없습니다.

이 문제는 Chrome 22.0.1229.94, FF 16.0.2Safari 6.0.1에서 발생합니다. 레일 3.2.8을 사용하고 있습니다.

아마도 관련 질문

It seems like this guy was having a very similar problem to me.

라이브 샘플 당신이 정말로 문제가 Heroku가 내 준비 서버에 살고 볼 수 있습니다 당신이 원하는 경우

.

대처 방안 (편집 :) 문제가 패치 된 이후로는 더 이상 작동하지 않습니다[email protected] 및 통과 : 이메일과 here

  1. 로그인
  2. 는 foobar 방문 http://print-staging.herokuapp.com/customers/2. 엉망인 대화 상자가 열리는 것을보아야합니다.
  3. 대화 상자에서 작은 "새 작업"링크를 클릭하십시오. 페이지가 변경되고 새 대화 상자가 열립니다.
  4. 브라우저의 뒤로 버튼을 클릭하십시오.

답변

9

당신은 서버 측에서 응답에 노 캐시 헤더를 추가 할 수 있습니다,이 응답을 캐시하지 브라우저를 지시한다 : 나는 백본을 사용하고 있지 않다

response.headers["Cache-Control"] = "no-cache" 
+1

하지만 왜 그렇게해야합니까? 실제로 브라우저가 대부분의 시간 동안 응답을 캐시하고 싶습니다 (아마도별로 변하지 않을 것입니다). 뒤로 버튼이 캐시 된 응답을 표시하는 것을 원하지 않습니다. 기본적으로 JSON 요청을 보내려고하지만 사용자가 뒤로 버튼을 누르면 JSON 요청이 아닌 HTML 요청을하고 싶습니다. –

+0

죄송합니다. David의 의미를 알 수 없습니다. 어떻게 캐싱을 사용하고 싶지만 뒤로 버튼에 캐시 된 응답을 표시하지 않으시겠습니까? – kabaros

+0

JSON GET 요청을 브라우저 히스토리 스택에 입력하지 않으려면 backbone과 함께 'pushState'를 사용하고 있음에도 불구하고 다시 버튼을 누르면 건너 뛸 수있는 방법이 필요합니다. JSON 요청을 통해 사용자에게 이전 요청을 표시합니다 (HTML 요청이 실제 페이지를 형성하여 사용자에게 표시 할 수 있어야 함). 아마도 이것이 불가능합니다. 확실하지 않습니다. –

2

을,이다 단지 제가 AJAX/pushstate


와 함께했던 내 AJAX 응답에서 history.pushState()를 사용합니다.

var url = "http://foo.com/path/to/page"; 
var relative_url = UrlToRelative(url); // some function to convert a URL to relative 
var absolute_url = UrlToAbsolute(url); // some function to convert a URL to absolute 
history.pushState(
    { 
    hash: "#"+relative_url, 
    title: document.title, 
    initialHref: absolute_url 
    }, 
    document.title, 
    url 
); 

은 내가 onPopState에 대한 이벤트 리스너를 가지고 :

window.onpopstate = function(event) { 
    if (event.state && event.state.initialHref) { 
    $.ajax({ 
     complete: null, 
     data: {}, 
     dataType: "script", 
     success: null, 
     type: 'GET', 
     url: event.state.initialHref 
    }); 
    } 
} 

이 이벤트 리스너는 AJAX 요청을한다. 유일한 문제는 서버 응답을 얻기 위해 몇 초가 걸리는 페이지로 돌아갈 때 화면이 변경되는 데 몇 초가 걸리는 것입니다. 스피너 또는 진행률 표시기가 없습니다.

관련 문제