sanfrancesco / prerendercloud-lambda-edge

Pre-render CloudFront with this Lambda@Edge function. Powered by https://headless-render-api.com (formerly named prerender.cloud from 2016 - 2022)
https://headless-render-api.com
MIT License
206 stars 35 forks source link

HTML files cannot be served #11

Closed otbe closed 6 years ago

otbe commented 6 years ago

Hi,

I guess its currently not possible to serve plain html files isnt it?

For example: I have a typical SPA which serves /, /about and /company. This works very well. Now I want to serve /bar.html which exists in my S3 Bucket. In my opinion all requests to HTML-like URLs are rewritten to /index.html due to this (and later this)

Usecase: We want to serve a Facebook verification page, see this

Do I miss something?

jotto commented 6 years ago

You did not miss anything, see bullet point 2 of the caveats section in the README.md:

This solution will serve index.html in place of something like /some-special-file.html even if /some-special-file.html exists on your origin

Potential solutions:

Let me know what you recommend.

otbe commented 6 years ago

Mh. I tried your advice and added a second guard expression (&& !uri.includes('...')) to the if statement but now I get a prerendered version of the file. I guess this not what facebook wants :/

The result looks like this:

<html><head><script type="text/javascript">(function (a) {
  // Head-Dedupe monkeypatch injected by https://www.prerender.cloud to make this JS app isomorphic
  // see https://github.com/sanfrancesco/prerendercloud-ajaxmonkeypatch

  function b(j){for(var l=[],m=j.length>>>0;m--;)l[m]=j[m];return l}function c(j,l){return"META"===l.tagName&&j.name&&"content"===j.name.toLowerCase()?"":l.getAttribute("rel")&&"canonical"===l.getAttribute("rel")&&j.name&&"href"===j.name.toLowerCase()?"":(j.name||"")+(j.value||"")}function d(j){var l=[];return Array.prototype.forEach.call(j.attributes||j.attrs,function(m){l.push(c(m,j))}),j.tagName+l.sort().join(",")}function e(j,l){return j&&l&&!(j.tagName!==l.tagName)&&("LINK"===j.tagName||"META"===j.tagName?d(j)===d(l):"STYLE"===j.tagName?j.innerHTML&&j.innerHTML.length&&j.innerHTML===l.innerHTML:j.outerHTML===l.outerHTML)}function f(j,l){var m=b(l.children).find(function(n){return e(j,n)});m&&l.removeChild(m)}Array.prototype.find||Object.defineProperty(Array.prototype,"find",{value:function value(j){if(null==this)throw new TypeError("\"this\" is null or not defined");var l=Object(this),m=l.length>>>0;if("function"!=typeof j)throw new TypeError("predicate must be a function");for(var q,n=arguments[1],p=0;p<m;){if(q=l[p],j.call(n,q,p,l))return q;p++}}});var g=a.Node.prototype.appendChild;a.Node.prototype.appendChild=function(j){try{return"HEAD"===this.nodeName&&f(j,this),g.apply(this,arguments)}catch(l){return g.apply(this,arguments)}};var h=a.Node.prototype.insertBefore;a.Node.prototype.insertBefore=function(j,l){try{if("HEAD"!==this.nodeName)return h.apply(this,arguments);if(e(j,l)){var m=h.apply(this,arguments);return this.removeChild(l),m}return f(j,this),h.apply(this,arguments)}catch(n){return h.apply(this,arguments)}}
})(window, '')</script><script type="text/javascript">(function (a, b) {
  // Ajax-Bypass monkeypatch injected by https://www.prerender.cloud to make this JS app isomorphic
  // see https://github.com/sanfrancesco/prerendercloud-ajaxmonkeypatch
  try {
    if(Array.prototype.indexOf){var c;try{c=b?JSON.parse(b):[]}catch(g){return}a.pcPathsToIgnore=c,String.prototype.startsWith||(String.prototype.startsWith=function(g,h){return!!g&&(h=h||0,this.substr(h,g.length)===g)});var d=function(g){var h=g.startsWith(a.location.origin),i=g.startsWith("/")&&!g.startsWith("//"),j=-1!==c.indexOf(g);return(h||i)&&!j},e=a.XMLHttpRequest.prototype.open;if(a.XMLHttpRequest.prototype.open=function(){var g=arguments[1],h=e.apply(this,arguments);return g&&d(g)&&this.setRequestHeader("x-prerendered","true"),h},a.fetch){var f=a.fetch;a.fetch=function(g,h){return g&&g.headers?(g&&g.url&&d(g.url)&&g.headers.set("x-prerendered",!0),f(g,h||g)):(g&&d(g)&&(h=h||{},h.headers=h.headers||{},h.headers["x-prerendered"]="true"),f(g,h))}}}
  } catch (error) {
    console.error('prerender.cloud ajax bypass monkeypatch parse failure', error);
  }

})(window, '[]')</script></head><body>
CONTENT FROM FACEBOOK
</body><!-- prerender.cloud processed at: 2018-05-09T12:04:54.115Z --></html>
jotto commented 6 years ago

Sorry about my previous comment which was wrong.

I updated the prerendercloud dependency which has a new option: blacklistPaths that should solve this.

git pull this project and yarn install to get the latest, then uncomment and edit: https://github.com/sanfrancesco/prerendercloud-lambda-edge/blob/ccd87b5484a4334d823dbb8f0df16e843b2dc910/handler.js#L81 as appropriate

After you verify that it works, close this issue.

otbe commented 6 years ago

Mh...cant get it working. Ive updated my project to use prerendercloud 1.35.0 and uncommented the blacklistPaths option as you suggested. But I still get the default index.html.

I checked the Cloudwatch logs, but there are no logs for this request in the origin request Lambda.

jotto commented 6 years ago

Sorry, again, about this @otbe. I just manually tested it myself, found the bug, fixed it and verified it again.

  1. git pull
  2. edit blacklistPaths in handler.js if necessary
  3. make deploy
  4. wait ~1 minute for CloudFront to invalidate
  5. clear browser cache (or open dev console, or use incognito)
otbe commented 6 years ago

Sorry for my late response! Works like a charm. Thank you very much (again :))