The problem is that the HTML parser gets confused if your script contains the closing script tag in it (</script>) and it closes the script tag prematurely.
The solution is to escape the / in "<\/script>". This works because strings in JavaScript, (and some other languages), any invalid escape sequences are just ignored, so "\l" is treated as "l", and "\/" is treated as "/". The HTML parser, however, doesn't use a backslash to escape them so it doesn't get confused (credits to https://stackoverflow.com/users/405681/keaukraine).
var scriptTag = "<script>alert(1)<\/script>";
$("#iframe").contents().find("body").append(scriptTag);
Original solution
Break up that closing tag so you don't mess up the HTML parser. The other solutions on this page work because they never have the string </script> in their code (jsfiddle):
var scriptTag = "<script>alert(1)<";
scriptTag += "/script>";
console.log(scriptTag);
$("#iframe").contents().find("body").append(scriptTag);
Or (jsfiddle):
var scriptTag = "<script>alert(1)<"+"/script>";
$("#iframe").contents().find("body").append(scriptTag);
<script>...</script>) or in an separate.jsfile?frames[0].window.$ = frames[0].window.jQuery = window.$;