Cách tải lại / làm mới một phần tử (hình ảnh) trong jQuery


262

Có thể tải lại một hình ảnh với tên tệp giống hệt từ máy chủ bằng jQuery không?

Ví dụ: tôi có một hình ảnh trên một trang, tuy nhiên, hình ảnh vật lý có thể thay đổi dựa trên hành động của người dùng. Lưu ý, điều này không có nghĩa là tên tệp thay đổi, mà là chính tệp thực tế.

I E:

  • Người dùng xem hình ảnh trên trang mặc định
  • Người dùng tải lên hình ảnh mới
  • Hình ảnh mặc định trên trang không thay đổi (Tôi cho rằng điều này là do tên tệp giống hệt nhau, trình duyệt sử dụng phiên bản được lưu trong bộ nhớ cache)

Bất kể tần suất mã dưới đây được gọi như thế nào, vấn đề tương tự vẫn tồn tại.

$("#myimg").attr("src", "/myimg.jpg");

Trong tài liệu jQuery, hàm "load" sẽ hoàn hảo nếu nó có một phương thức mặc định để phát sinh sự kiện trái ngược với ràng buộc hàm gọi lại với tải thành công / hoàn chỉnh của một phần tử.

Bất kỳ trợ giúp được đánh giá rất cao.


1
@Alexis, vấn đề của bạn là hình ảnh được lưu trong trình duyệt và sẽ không cập nhật sau khi nó được thay đổi trên máy chủ?
jay

1
@jeerose, tôi tin rằng đây là vấn đề vì tập tin thực sự thay đổi (cùng tên tệp) và được phản ánh trên trang nếu bạn làm mới toàn bộ trang.
Alexis Abril

Câu trả lời:


551

Có vẻ như trình duyệt của bạn lưu trữ hình ảnh (mà bây giờ tôi nhận thấy bạn đã viết trong câu hỏi của bạn). Bạn có thể buộc trình duyệt tải lại hình ảnh bằng cách chuyển một biến phụ như vậy:

d = new Date();
$("#myimg").attr("src", "/myimg.jpg?"+d.getTime());

1
Thêm một biến chuỗi truy vấn hoàn toàn vượt qua tâm trí của tôi. Điều này đã giải quyết nó và hình ảnh bây giờ tải lại theo yêu cầu.
Alexis Abril

45
gangsta tip, thích nó
Dave Jellison

4
Nó hoạt động, và nó là một cách giải quyết tốt, nhưng vẫn là một cách giải quyết! Có cách nào khác để tìm nạp hình ảnh nói cho trình duyệt quên đi cái đã lưu trong bộ nhớ cache không?
spuas

Tôi có một webcam thực sự kén chọn dường như cấm mọi yêu cầu đối với hình ảnh tĩnh có chứa tham số. Ừ Đây là một giải pháp tuyệt vời khác.
dangowans

3
@TomasGonzalez B / c có một cơ hội nhận được một vụ va chạm với random, và không bao giờ nên được với Datetrừ khi bạn thực sự thực sự nhanh chóng. ; ^) Nhận một ngày trên máy khách không phải là tài nguyên chuyên sâu và bạn có thể sử dụng lại nhiều hình ảnh mà bạn cần để lấy cùng một lúc, vì vậy hãy chuyển sang bước 4. Lợi nhuận.
ruffin

57

Đây có thể không phải là cách tốt nhất, nhưng trước đây tôi đã giải quyết vấn đề này bằng cách thêm dấu thời gian vào URL hình ảnh bằng JavaScript:

$("#myimg").attr("src", "/myimg.jpg?timestamp=" + new Date().getTime());

Lần tải sau, dấu thời gian được đặt thành thời gian hiện tại và URL khác nhau, do đó trình duyệt thực hiện GET cho hình ảnh thay vì sử dụng phiên bản được lưu trong bộ nhớ cache.


2
Điều này làm việc cho tôi trong nhiều năm, nhưng hôm nay máy chủ hình ảnh của tôi (không do tôi kiểm soát) bắt đầu trả về một liên kết bị hỏng nếu tên tệp không chính xác. Nếu bất cứ ai có cách giải quyết khác, nó sẽ được đánh giá cao. Thật không may, mỗi câu trả lời trong chủ đề này là một biến thể của câu hỏi này.
felwithe

@felwithe, có thể máy chủ này chỉ tìm phần mở rộng khi kết thúc truy vấn? Vì vậy, bạn có thể thử kiểm tra phương pháp này: imagename.jpg?t=1234567&q=.jpghoặcimagename.jpg#t1234567.jpg
FlameStorm

26

Đây có thể là một trong hai vấn đề bạn đề cập đến chính mình.

  1. Máy chủ đang lưu trữ hình ảnh
  2. JQuery không kích hoạt hoặc ít nhất là không cập nhật thuộc tính

Thành thật mà nói, tôi nghĩ đó là số hai. Sẽ dễ dàng hơn rất nhiều nếu chúng ta có thể thấy thêm một số jQuery. Nhưng để bắt đầu, hãy thử xóa thuộc tính trước, sau đó đặt lại. Chỉ để xem nếu điều đó giúp:

$("#myimg").removeAttr("src").attr("src", "/myimg.jpg");

Ngay cả khi điều này hoạt động, hãy đăng một số mã vì điều này không tối ưu, imo :-)


@Kordonme, đây có phải là nơi mà ai đó nhận xét về jQuery "xấu" không? (Tôi đang nói đùa, tôi nói đùa);)
jay

@Kordonme, điều này thực sự được tổ chức trong một trình xử lý sự kiện và tại thời điểm này là dòng mã duy nhất. Tôi đã thêm một cảnh báo ngay trước dòng này chỉ để xác minh sự kiện đang thực sự diễn ra. Sự kiện này không có lỗi.
Alexis Abril

3
Tôi có một webcam thực sự kén chọn dường như cấm mọi yêu cầu đối với hình ảnh tĩnh có chứa tham số. Ừ Đây là một giải pháp tuyệt vời cho trường hợp độc đáo của tôi. Cảm ơn.
dangowans

Đây là câu trả lời tốt nhất nếu bạn không muốn / cần các thông số còn lại
RafaSashi

Cảm ơn vì điều này đã giúp (nó chỉ lưu nó cho tôi trong Chrome)
Daniel Resch

14

với một dòng không phải lo lắng về việc mã hóa hình ảnh src vào javascript (nhờ jeerose cho các ý tưởng:

$("#myimg").attr("src", $("#myimg").attr("src")+"?timestamp=" + new Date().getTime());

13
Hãy cẩn thận vì điều này sẽ vô cùng thêm ngày càng nhiều ký tự vào cuối URL
Alfo

9

Để bỏ qua bộ nhớ đệm tránh thêm dấu thời gian vô hạn vào url hình ảnh, hãy loại bỏ dấu thời gian trước đó trước khi thêm dấu thời gian mới, đây là cách tôi đã thực hiện.

//refresh the image every 60seconds
var xyro_refresh_timer = setInterval(xyro_refresh_function, 60000);

function xyro_refresh_function(){
//refreshes an image with a .xyro_refresh class regardless of caching
    //get the src attribute
    source = jQuery(".xyro_refresh").attr("src");
    //remove previously added timestamps
    source = source.split("?", 1);//turns "image.jpg?timestamp=1234" into "image.jpg" avoiding infinitely adding new timestamps
    //prep new src attribute by adding a timestamp
    new_source = source + "?timestamp="  + new Date().getTime();
    //alert(new_source); //you may want to alert that during developement to see if you're getting what you wanted
    //set the new src attribute
    jQuery(".xyro_refresh").attr("src", new_source);
}

6

Điều này làm việc tuyệt vời! tuy nhiên nếu bạn tải lại src nhiều lần, dấu thời gian cũng được nối với url. Tôi đã sửa đổi câu trả lời được chấp nhận để đối phó với điều đó.

$('#image_reload_button').on('click', function () {
    var img = $('#your_image_selector');
    var src = img.attr('src');
    var i = src.indexOf('?dummy=');
    src = i != -1 ? src.substring(0, i) : src;

    var d = new Date();
    img.attr('src', src + '?dummy=' + d.getTime());
});

3

Bạn đã thử thiết lập lại các thùng chứa hình ảnh html. Tất nhiên, nếu đó là trình duyệt lưu vào bộ đệm thì điều này sẽ không có ích.

function imageUploadComplete () {
    $("#image_container").html("<img src='" + newImageUrl + "'>");
}

2

Đôi khi giải pháp thực sự như -

$("#Image").attr("src", $('#srcVal').val()+"&"+Math.floor(Math.random()*1000));

cũng không làm mới src đúng cách, hãy thử nó, nó hoạt động với tôi ->

$("#Image").attr("src", "dummy.jpg");
$("#Image").attr("src", $('#srcVal').val()+"&"+Math.floor(Math.random()*1000));

1

Sử dụng "#" làm dấu phân cách có thể hữu ích

Hình ảnh của tôi được lưu trong thư mục "ẩn" phía trên "www" để chỉ những người dùng đã đăng nhập mới được phép truy cập chúng. Vì lý do này, tôi không thể sử dụng thông thường <img src=/somefolder/1023.jpg>nhưng tôi gửi yêu cầu đến máy chủ <img src=?1023>và nó phản hồi bằng cách gửi lại hình ảnh được giữ dưới tên '1023'.

Ứng dụng này được sử dụng để cắt xén hình ảnh, vì vậy sau khi yêu cầu ajax cắt xén hình ảnh, nó được thay đổi dưới dạng nội dung trên máy chủ nhưng vẫn giữ nguyên tên gốc. Để xem kết quả của việc cắt xén, sau khi yêu cầu ajax được hoàn thành, hình ảnh đầu tiên được xóa khỏi DOM và một hình ảnh mới được chèn cùng tên <img src=?1023>.

Để tránh rút tiền mặt, tôi thêm vào yêu cầu thẻ "thời gian" được đặt trước "#" để nó trở nên như thế <img src=?1023#1467294764124>. Máy chủ sẽ tự động lọc phần băm của yêu cầu và trả lời chính xác bằng cách gửi lại hình ảnh của tôi được giữ ở dạng '1023'. Do đó, tôi luôn nhận được phiên bản cuối cùng của hình ảnh mà không cần giải mã nhiều phía máy chủ.


1
Tại sao phải trải qua tất cả những rắc rối để phục vụ một hình ảnh? Có vẻ như một rắc rối vô nghĩa
lucasreta

0

Tôi có thể phải tải lại nguồn hình ảnh nhiều lần. Tôi đã tìm thấy một giải pháp với Lodash phù hợp với tôi:

$("#myimg").attr('src', _.split($("#myimg").attr('src'), '?', 1)[0] + '?t=' + _.now());

Dấu thời gian hiện tại sẽ bị cắt ngắn và thay thế bằng dấu thời gian mới.


-1

Dựa trên câu trả lời của @kasper Taeymans.

Nếu bạn chỉ cần tải lại hình ảnh (không thay thế src bằng smth new), hãy thử:

$(function() {
  var img = $('#img');

  var refreshImg = function(img) {
    // the core of answer is 2 lines below
    var dummy = '?dummy=';
    img.attr('src', img.attr('src').split(dummy)[0] + dummy + (new Date()).getTime());

    // remove call on production
    updateImgVisualizer();
  };


  // for display current img url in input
  // for sandbox only!
  var updateImgVisualizer = function() {
    $('#img-url').val(img.attr('src'));
  };

  // bind img reload on btn click
  $('.img-reloader').click(function() {
    refreshImg(img);
  });

  // remove call on production
  updateImgVisualizer();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<img id="img" src="http://dummyimage.com/628x150/">


<p>
  <label>
    Current url of img:
    <input id="img-url" type="text" readonly style="width:500px">
  </label>
</p>

<p>
  <button class="img-reloader">Refresh</button>
</p>


-2

Tôi chỉ đơn giản làm điều này trong html:

<script>
    $(document).load(function () {
        d = new Date();
        $('#<%= imgpreview.ClientID %>').attr('src','');
    });
</script>

Và tải lại hình ảnh trong mã phía sau như thế này:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        image.Src = "/image.jpg"; //url caming from database
    }

}


1
Tải lại trang và cài đặt trong asp.NET WebForms không thực sự thuộc chủ đề ở đây.
Jonas Stensved
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.