วิธีโหลด / รีเฟรชองค์ประกอบ (ภาพ) ใน jQuery


262

เป็นไปได้หรือไม่ที่จะโหลดรูปภาพที่มีชื่อไฟล์เหมือนกันจากเซิร์ฟเวอร์โดยใช้ jQuery

ตัวอย่างเช่นฉันมีภาพในหน้าอย่างไรก็ตามภาพทางกายภาพสามารถเปลี่ยนแปลงได้ขึ้นอยู่กับการกระทำของผู้ใช้ หมายเหตุนี่ไม่ได้หมายความว่าชื่อไฟล์จะเปลี่ยน แต่เป็นไฟล์จริง

เช่น:

  • ผู้ใช้ดูภาพในหน้าเริ่มต้น
  • ผู้ใช้อัปโหลดภาพใหม่
  • รูปภาพเริ่มต้นบนหน้าไม่เปลี่ยนแปลง (ฉันถือว่านี่เป็นเพราะชื่อไฟล์เหมือนกันเบราว์เซอร์ใช้เวอร์ชันแคช)

ไม่ว่าจะมีการเรียกใช้รหัสด้านล่างบ่อยแค่ไหนปัญหาเดียวกันก็ยังคงมีอยู่

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

ในเอกสารประกอบ jQuery ฟังก์ชัน "load" จะสมบูรณ์แบบหากมีวิธีการเริ่มต้นในการ firing เหตุการณ์เมื่อเทียบกับการโยงฟังก์ชัน callback กับการโหลดที่สำเร็จ / สมบูรณ์ขององค์ประกอบ

ความช่วยเหลือใด ๆ ที่ชื่นชมอย่างมาก


1
@Alexis เป็นปัญหาของคุณที่ภาพแคชในเบราว์เซอร์และจะไม่ปรับปรุงหลังจากที่มีการเปลี่ยนแปลงบนเซิร์ฟเวอร์?
jay

1
@eerose ฉันเชื่อว่านี่เป็นปัญหาเนื่องจากไฟล์มีการเปลี่ยนแปลงจริง ๆ (ชื่อไฟล์เดียวกัน) และจะปรากฏบนหน้าหากคุณทำการรีเฟรชหน้าเต็ม
Alexis Abril

คำตอบ:


551

ดูเหมือนว่าเบราว์เซอร์ของคุณจะแคชรูปภาพ (ซึ่งตอนนี้ฉันสังเกตเห็นว่าคุณเขียนไว้ในคำถามของคุณ) คุณสามารถบังคับให้เบราว์เซอร์โหลดภาพซ้ำโดยส่งตัวแปรพิเศษดังนี้:

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

1
การเพิ่มตัวแปรสตริงข้อความค้นหาส่งผ่านจิตใจของฉันอย่างสมบูรณ์ วิธีนี้แก้ไขได้และภาพจะโหลดตามคำขอ
Alexis Abril

45
เคล็ดลับอันธพาลรักมัน
Dave Jellison

4
มันใช้งานได้และมันก็เป็นวิธีการแก้ปัญหาที่ดี แต่ก็ยังคงเป็นวิธีแก้ปัญหา! ไม่มีวิธีการดึงภาพที่บอกเบราว์เซอร์ให้ลืมเรื่องแคชหรือไม่?
spuas

ฉันมีเว็บแคมจู้จี้จุกจิกจริงๆที่ดูเหมือนจะห้ามคำขอใด ๆ สำหรับภาพคงที่ที่มีพารามิเตอร์ ฮึ. นี่เป็นทางออกที่ดีอย่างอื่น
dangowans

3
@TomasGonzalez B / C มีเป็นโอกาสของการปะทะกันกับที่randomและไม่ควรที่เคยอยู่กับDateถ้าคุณจริงๆอย่างรวดเร็ว ; ^) การออกเดทกับลูกค้านั้นไม่ใช่ทรัพยากรที่เข้มข้นและคุณสามารถใช้รูปภาพซ้ำได้มากเท่าที่คุณต้องการในคราวเดียวดังนั้นทำตามขั้นตอนที่ 4 กำไร
ruffin

57

อาจไม่ใช่วิธีที่ดีที่สุด แต่ฉันได้แก้ไขปัญหานี้ในอดีตโดยเพียงแค่เพิ่มการประทับเวลาลงใน URL ภาพโดยใช้ JavaScript:

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

ครั้งต่อไปที่โหลดโหลดประทับเวลาจะถูกตั้งค่าเป็นเวลาปัจจุบันและ URL แตกต่างกันดังนั้นเบราว์เซอร์จะรับ GET สำหรับภาพแทนที่จะใช้เวอร์ชันแคช


2
สิ่งนี้ใช้ได้กับฉันมาหลายปี แต่วันนี้เซิร์ฟเวอร์รูปภาพของฉัน (ไม่ได้ควบคุมโดยฉัน) เริ่มส่งคืนลิงก์ที่เสียหายถ้าชื่อไฟล์ไม่ถูกต้อง หากใครมีวิธีแก้ปัญหาอื่นก็จะได้รับการชื่นชมมาก น่าเสียดายที่คำตอบทุกข้อในกระทู้นี้เป็นคำตอบที่หลากหลาย
felwithe

@felwithe เซิร์ฟเวอร์นี้อาจค้นหาเฉพาะส่วนขยายในส่วนท้ายของแบบสอบถามหรือไม่ ดังนั้นคุณสามารถลองทดสอบวิธีนี้: imagename.jpg?t=1234567&q=.jpgหรือimagename.jpg#t1234567.jpg
FlameStorm

26

นี่อาจเป็นหนึ่งในสองปัญหาที่คุณพูดถึงตัวคุณเอง

  1. เซิร์ฟเวอร์กำลังแคชอิมเมจ
  2. jQuery ไม่เริ่มทำงานหรืออย่างน้อยก็ไม่อัปเดตแอตทริบิวต์

พูดตามตรงฉันคิดว่ามันเป็นอันดับสอง คงจะง่ายกว่านี้ถ้าเราเห็น jQuery เพิ่มขึ้น แต่สำหรับการเริ่มต้นให้ลองลบแอตทริบิวต์ก่อนแล้วจึงตั้งค่าอีกครั้ง เพียงเพื่อดูว่าจะช่วยให้:

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

แม้ว่าวิธีนี้จะใช้ได้ผลโปรดโพสต์โค้ดบางส่วนเนื่องจากไม่เหมาะสม imo :-)


@Kordonme นี่คือสิ่งที่ใครบางคนแสดงความคิดเห็นเกี่ยวกับ "ไม่ดี" jQuery? (ฉันล้อเล่นฉันล้อเล่น);)
jay

@ Kordonme นี่ถูกจัดขึ้นจริงในตัวจัดการเหตุการณ์และในขณะนี้คือบรรทัดของรหัสเท่านั้น ฉันได้เพิ่มการแจ้งเตือนก่อนบรรทัดนี้เพียงเพื่อยืนยันว่าเหตุการณ์กำลังเริ่มขึ้นจริง เหตุการณ์เริ่มทำงานโดยไม่มีข้อผิดพลาด
Alexis Abril

3
ฉันมีเว็บแคมจู้จี้จุกจิกจริงๆที่ดูเหมือนจะห้ามคำขอใด ๆ สำหรับภาพคงที่ที่มีพารามิเตอร์ ฮึ. นี่เป็นทางออกที่ดีสำหรับกรณีเฉพาะของฉัน ขอบคุณ
dangowans

นี่เป็นคำตอบที่ดีที่สุดหากคุณไม่ต้องการ / ต้องการพารามิเตอร์ที่เหลือ
RafaSashi

ขอบคุณสิ่งนี้ช่วยได้ (มันใช้ได้เฉพาะกับฉันใน Chrome)
Daniel Resch

14

ด้วยหนึ่งบรรทัดโดยไม่ต้องกังวลเกี่ยวกับการเข้ารหัสภาพ src ลงในจาวาสคริปต์ (ขอบคุณที่ jeerose สำหรับแนวคิด:

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

13
เพียงแค่ต้องระวังเพราะสิ่งนี้จะเพิ่มตัวละครมากขึ้นเรื่อย ๆ ไปยังจุดสิ้นสุดของ URL
Alfo

9

หากต้องการข้ามการแคชและหลีกเลี่ยงการเพิ่มการประทับเวลาที่ไม่สิ้นสุดลงใน URL ของภาพให้ตัดการประทับเวลาก่อนหน้านี้ก่อนที่จะเพิ่มใหม่นี่คือวิธีที่ฉันทำ

//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

มันใช้งานได้ดี! อย่างไรก็ตามหากคุณโหลด src ซ้ำหลาย ๆ ครั้งการประทับเวลาจะถูกต่อกับ url ด้วย ฉันได้แก้ไขคำตอบที่ยอมรับเพื่อจัดการกับสิ่งนั้น

$('#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

คุณลองรีเซ็ต html คอนเทนเนอร์รูปภาพแล้วหรือยัง แน่นอนถ้ามันเป็นเบราว์เซอร์ที่แคชแล้วนี่จะไม่ช่วยอะไร

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

2

บางครั้งวิธีแก้ปัญหาเช่น -

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

ยังไม่รีเฟรช src อย่างถูกต้องลองใช้มันใช้ได้กับฉัน ->

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

1

การใช้ "#" เป็นตัวคั่นอาจมีประโยชน์

ภาพของฉันถูกเก็บไว้ในโฟลเดอร์ "ซ่อน" ด้านบน "www" เพื่อให้ผู้ใช้ที่เข้าสู่ระบบเท่านั้นที่ได้รับอนุญาตให้เข้าถึงได้ ด้วยเหตุนี้ฉันไม่สามารถใช้สามัญ<img src=/somefolder/1023.jpg>แต่ฉันส่งคำขอไปยังเซิร์ฟเวอร์เช่น<img src=?1023>นั้นและตอบกลับโดยส่งรูปภาพที่เก็บไว้ภายใต้ชื่อ '1023'

แอปพลิเคชันใช้สำหรับการครอบตัดรูปภาพดังนั้นหลังจาก ajax ร้องขอให้ครอบตัดรูปภาพจะมีการเปลี่ยนแปลงเป็นเนื้อหาบนเซิร์ฟเวอร์ แต่เก็บชื่อดั้งเดิมไว้ เพื่อดูผลลัพธ์ของการครอบตัดหลังจากคำขอ ajax เสร็จสมบูรณ์รูปภาพแรกจะถูกลบออกจาก DOM และรูปภาพใหม่จะถูกแทรกด้วยชื่อเดียวกัน<img src=?1023>และภาพใหม่จะถูกแทรกที่มีชื่อเดียวกัน

เพื่อหลีกเลี่ยงการ cashing ฉันเพิ่มในคำขอแท็ก "เวลา" ที่เติมด้วย "#" ดังนั้นจึงเป็นเช่น<img src=?1023#1467294764124>นั้น เซิร์ฟเวอร์จะกรองส่วนแฮชของคำขอโดยอัตโนมัติและตอบกลับอย่างถูกต้องโดยส่งภาพของฉันที่เก็บไว้เป็น '1023' ดังนั้นฉันจะได้รับเวอร์ชันล่าสุดของอิมเมจโดยไม่ต้องถอดรหัสฝั่งเซิร์ฟเวอร์มาก


1
ทำไมต้องผ่านทุกปัญหาในการแสดงภาพ? ดูเหมือนจะเป็นเรื่องยุ่งยากไร้สาระ
lucasreta

0

ฉันอาจต้องโหลดแหล่งที่มาของภาพซ้ำหลายครั้ง ฉันพบวิธีแก้ปัญหากับLodashที่ทำงานได้ดีสำหรับฉัน:

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

การประทับเวลาที่มีอยู่จะถูกตัดทอนและแทนที่ด้วยใหม่


-1

ตามคำตอบของ @kasper Taeymans

หากคุณต้องการรูปภาพที่โหลดซ้ำ (ไม่ได้แทนที่มันคือ src ด้วย smth ใหม่) ให้ลอง:

$(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

ฉันเพิ่งทำสิ่งนี้ใน html:

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

และโหลดภาพในโค้ดด้านหลังดังนี้:

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

}


1
การโหลดหน้าซ้ำและการตั้งค่าใน asp.net WebForms ไม่ได้อยู่ในหัวข้อจริงๆที่นี่
Jonas Stensved
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.