diff --git a/lti_consumer/static/js/xblock_lti_consumer.js b/lti_consumer/static/js/xblock_lti_consumer.js
index 8a8070593eae3d110df2903f081fe210dd382d86..60b2c63965e711d132e6939cc829f275f1a9e364 100644
--- a/lti_consumer/static/js/xblock_lti_consumer.js
+++ b/lti_consumer/static/js/xblock_lti_consumer.js
@@ -16,6 +16,9 @@ function LtiConsumerXBlock(runtime, element) {
                 return this.each(function () {
                     var o = options;
                     $(this).click(function (e) {
+                        var $modal = $(modal_id);
+                        // Set iframe src attribute to launch LTI provider
+                        $modal.find('iframe').attr('src', $modal.data('launch-url'));
                         $("#" + overlay_id).click(function () {
                             close_modal(modal_id)
                         });
@@ -56,10 +59,12 @@ function LtiConsumerXBlock(runtime, element) {
                     });
                 });
                 function close_modal(modal_id) {
+                    var $modal = $(modal_id);
                     $('select, input, textarea, button, a').off('focus');
                     $("#" + overlay_id).fadeOut(200);
-                    $(modal_id).css({"display": "none"});
-                    $(modal_id).attr('aria-hidden', true);
+                    $modal.css({"display": "none"});
+                    $modal.attr('aria-hidden', true);
+                    $modal.find('iframe').attr('src', '');
                     $('body').css('overflow', 'auto');
                     $trigger.focus();
                 }
diff --git a/lti_consumer/templates/html/lti_iframe.html b/lti_consumer/templates/html/lti_iframe.html
index 76841fce6725823933dac70bf238057aff235ba6..7233ecee93fd9416a9527c6dcb7191160492bd42 100644
--- a/lti_consumer/templates/html/lti_iframe.html
+++ b/lti_consumer/templates/html/lti_iframe.html
@@ -1,8 +1,9 @@
+<%page args="initial_launch_url" expression_filter="h"/>
 <iframe
     title="${display_name}"
     class="ltiLaunchFrame"
     name="ltiFrame-${element_id}"
-    src="${form_url}"
+    src="${initial_launch_url}"
     allowfullscreen="true"
     webkitallowfullscreen="true"
     mozallowfullscreen="true"
diff --git a/lti_consumer/templates/html/student.html b/lti_consumer/templates/html/student.html
index 421a42c314fbfa4dd39509e6ce871852fb921f17..59f85a629c8b53a16665e3f3e9241c7c2bedb3e4 100644
--- a/lti_consumer/templates/html/student.html
+++ b/lti_consumer/templates/html/student.html
@@ -51,6 +51,7 @@
             class="modal lti-modal"
             aria-hidden="true"
             style="width:${modal_width}%; left:${modal_horizontal_offset}%; top:${modal_vertical_offset}%; bottom:${modal_vertical_offset}%;"
+            data-launch-url="${form_url}"
         >
             <div class="inner-wrapper" role="dialog">
                 <button class="close-modal">
@@ -58,14 +59,17 @@
                     <span class="sr">Close</span>
                 </button>
                 ## The result of the LTI launch form submit will be rendered here.
-                <%include file="templates/html/lti_iframe.html"/>
+                ## initial_launch_url is set to an empty string here because
+                ## in "modal" launch mode, we use javascript to set the src
+                ## attribute of the iframe when the modal window is opened.
+                <%include file="templates/html/lti_iframe.html" args="initial_launch_url=''"/>
             </div>
         </section>
     % endif
     % if launch_target == 'iframe':
         <div style="height:${inline_height}px;">
             ## The result of the LTI launch form submit will be rendered here.
-            <%include file="templates/html/lti_iframe.html"/>
+            <%include file="templates/html/lti_iframe.html" args="initial_launch_url=form_url"/>
         </div>
     % endif
 % elif not hide_launch: