Laravel-Snappy/wkhtmltopdf doesnt work with Javascript and external assets - javascript

Ive been stuck here for hours trying to figure out whats wrong with this thing. It works when I exclude/comment out the javascript part but not when its uncommented. Another problem I faced is adding external assets to the view using {{ asset('js/app.js') }}. I tried {{ url(...) }}, {{ public_path(...) }} since it worked on some people after my research but chrome returns an error Not allowed to load local resource, i just need this to add jquery. If theres an alternative way to adding jquery pls tell me, tried CDN to no avail
I switched from dompdf to snappy BECAUSE I heard it works with javascript but now im stuck. I really need help.
version:
Windows 64-bit: wkhtmltopdf 0.12.6 (with patched qt)
Controller
<?php
namespace App\Http\Controllers;
use Barryvdh\Snappy\Facades\SnappyPdf as PDF;
class AsdController extends Controller
{
public function index()
{
$pdf = PDF::loadView('asd.index');
$pdf->setOption('enable-javascript', true);
$pdf->setOption('javascript-delay', 13500);
$pdf->setOption('enable-smart-shrinking', true);
$pdf->setOption('no-stop-slow-scripts', true);
return $pdf->download('asd.pdf');
}
}
VIEW
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<h1 id="sss">This is a Heading</h1>
<p>This is a paragraph.</p>
</body>
<script>
document.getElementById('sss').innerHTML = 'HAHA';
</script>
</html>
the error WITHOUT external assets but with javascript
The exit status code '-1073741819' says something went wrong: stderr: "Loading pages (1/6)
[> ] 0%
[======> ] 10%
[==============================> ] 50%
" stdout: "" command: "C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf"
--lowquality --enable-javascript --javascript-delay "13500" --enable-smart-shrinking
--no-stop-slow-scripts
the error WITH external assets and javascript
The exit status code '-1073741819' says something went wrong: stderr: "Loading pages (1/6)
[> ] 0%
[======> ] 10%
[==============================> ] 50%
Warning: Failed to load http://localhost:8000/js/app.js (ignore)
" stdout: "" command: "C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf"
--lowquality --enable-javascript --javascript-delay "13500"
--enable-smart-shrinking --no-stop-slow-scripts

I had the same problem on Windows x64 machine.
wkhtmltopdf disables local file access by default in the 0.12.6 version.
For those that are using laravel-snappy, add the 'enable-local-file-access' option in the config\snappy.php:
'pdf' => [
'enabled' => true,
'binary' => env('WKHTML_PDF_BINARY', '/usr/local/bin/wkhtmltopdf'),
'timeout' => false,
'options' => [
'enable-local-file-access' => true,
'orientation' => 'landscape',
'encoding' => 'UTF-8'
],
'env' => [],
],
'image' => [
'enabled' => true,
'binary' => env('WKHTML_IMG_BINARY', '/usr/local/bin/wkhtmltoimage'),
'timeout' => false,
'options' => [
'enable-local-file-access' => true,
'orientation' => 'landscape',
'encoding' => 'UTF-8'
],
'env' => [],
],

Related

output images corrupt when using mdx-bundler + remark-mdx-images

I am writing a site using the remix JavaScript framework.
It is a blog that uses MDX for the blog content. I want to include images within this content.
Background
I am using a combination of mdx-bundler to convert the MDX files into bundles, and the remark-mdx-images plugin to convert the markdown-style image references into image tags.
The Problem:
mdx-bundler is correctly building my Markdown, and is outputting the Image assets into the expected directory. However, the output images appear to be corrupt. I cannot open them in macos Finder. In-browser, requests for these images returns a 200, but the image is not visible.
Here is an example MDX file:
---
slug: hello-world
title: Hello, world
---
testing images
![](./hello-world.png 'Hello World')
Below is the relevant portion of remix config where these two things are used:
const { code, frontmatter } = await bundleMDX({
source: indexFile.content,
files: filesObject,
mdxOptions: options => ({
remarkPlugins: [
...(options.remarkPlugins ?? []),
remarkMdxImages,
remarkSlug,
remarkGfm,
],
rehypePlugins: [
...(options.rehypePlugins ?? []),
[rehypeAutolinkHeadings, { behavior: 'wrap' }],
[rehypePrettyCode, rehypePrettyCodeOptions],
],
}),
esbuildOptions: options => {
options.loader = {
...options.loader,
'.gif': 'file',
'.jpeg': 'file',
'.jpg': 'file',
'.png': 'file',
'.svg': 'file',
'.webp': 'file',
}
// Set write to true so that esbuild will output the files.
options.write = true
options.outdir = path.resolve(`public/build/_assets/${rootDir}/img`)
options.publicPath = path.resolve(`/build/_assets/${rootDir}/img`)
return options
},
})
I'm not entirely sure how to go about debugging this as I am new to MDX, mdx-bundler and remark-mdx-images. All of the output files and locations appear to be correct, it's just the image assets themselves that are corrupted.

Laravel Get File Contents of Image but Not Working on Production Environment

My code bellow working on localhost development
<img class="img-fluid rounded-circle" src="{{ url('image?type=user&file='.Auth::user()->picture_file.'&mime='.Auth::user()->picture_mime) }}" alt="Image Description">
will access imageController with get method using this link image?type=user&file=USER000053.png&mime=image/png
class ImageController extends BaseController
{
public function get(Request $request){
$file=Storage::disk($request->type)->get($request->file);
return response($file,200)->header('content-Type',$request->mime);
}
}
bellow my filesystem.php config file
'user' => [
'driver' => 'local',
'root' => storage_path('app/user'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
that code above works well on localhost. but when we tried to push to production server (centos os), that code won't works. Its just returning a damage image.
we have tried
[check] make sure storage and temp accessible. chmod 755. even we have tried 777
[check] chown to user apache.apache
[check] set selinux permisive mode
[check] we have make sure that file already exists
$file_exists = Storage::disk($request->type)->exists($request->file);
the code above return true
[check] trying this code bellow
$response = Response::make($file, 200);
$response->header('Content-Type', $request->mime);
return $response;
still won't work
trying to make symlink
php artisan storage:link
its makes symlink on public folder but still won't work
trying to download and still doesn't works
return response()->download(storage_path('app/' . $request->type . "/" . $request->file));
I'm running on Centos 7 Environment at GCP. any idea would be help me. thank you
update 1
Here are the result from our server
update 2
I have already check for that image on server and its fine and could be read
update 3
We have do this
$img = file_get_contents(public_path("storage/user/" . $request->file));
return response($img)->header('Content-type','image/png');
still not working
update 4
we make our own symbolic link on public folder as bellow
storage -> /var/www/html/*****/storage/app/
still not working
update 5
I have directly accessing file through browser, it comes up with the picture.
update 6
Have already set FILESYSTEM_DRIVER=local or FILESYSTEM_DRIVER=useron env file and still doesn't works
update 7
filesystem.php
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
'calculate_disk' => [
'driver' => 'local',
'root' => storage_path('app/calculate'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
'user' => [
'driver' => 'local',
'root' => storage_path('app/user'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
'invoice' => [
'driver' => 'local',
'root' => storage_path('app/invoice'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
],
],
web.php
Route::get('/image', 'ImageController#get');
update 8
after digging a while of FileSystemDriver I was curious about bellow url value that linked to localhost instead of our url. any idea?
FilesystemAdapter {#479 ▼
#driver: Filesystem {#482 ▼
#adapter: Local {#475 ▼
#pathSeparator: "/"
#permissionMap: array:2 [▼
"file" => array:2 [▼
"public" => 420
"private" => 384
]
"dir" => array:2 [▼
"public" => 493
"private" => 448
]
]
#writeFlags: 2
-linkHandling: 2
#pathPrefix: "/var/www/html/***/storage/app/user/"
}
#plugins: []
#config: Config {#477 ▼
#settings: array:2 [▼
"url" => "http://localhost/storage"
"visibility" => "public"
]
#fallback: null
}
}
}
Just add ob_get_clean(); before response file. It will clean all buffers and return content to display image.
If command ob_get_clean(); helps you, check your code on extra whitespaces before __<?php .

Inline Js with Vue-Meta In Nuxt.js

Basically, Im using Nuxt 2.9.2, and trying to using innerHTML method to inline a Google Optimize script, but whenever i run npm run generate, the code transforms certain aspects even though __dangerouslyDisableSanitizers is whitelisting innerHTML..
This is my Script in Nuxt Config head object
script: [
{
innerHTML: `(function(a,s,y,n,c,h,i,d,e){s.className+=' '+y;h.start=1*new Date;h.end=i=function(){s.className=s.className.replace(RegExp(' ?'+y),'')};(a[n]=a[n]||[]).hide=h;setTimeout(function(){i();h.end=null},c);h.timeout=c;})(window,document.documentElement,'async-hide','dataLayer', 500 , ${JSON.stringify(
{ [process.env.GOOGLE_OPTIMIZE_ID]: true }
)})`
}
],
__dangerouslyDisableSanitizers: ['innerHTML']
},
Which renders out as the below, tried multiple different ways. could not get it to inline as expected
!function(e,n,t,a,c,s,d){n.className+=" "+t,s.start=1*new Date,s.end=d=function(){n.className=n.className.replace(RegExp(" ?"+t),"")},(e[a]=e[a]||[]).hide=s,setTimeout(function(){d(),s.end=null},500),s.timeout=500}(window,document.documentElement,"async-hide","dataLayer",0,{"GTM-XXXXXX":!0})
should be
(function(a,s,y,n,c,h,i,d,e){s.className+=' '+y;h.start=1*new Date;h.end=i=function(){s.className=s.className.replace(RegExp(' ?'+y),'')};(a[n]=a[n]||[]).hide=h;setTimeout(function(){i();h.end=null},c);h.timeout=c;})(window,document.documentElement,'async-hide','dataLayer', 500 , 'GTM-XXXXXX'': true }
)})
script: [
{
innerHTML: `window.MY_CONST = 'abcd1234'`,
type: 'text/javascript',
charset: 'utf-8',
},
],
__dangerouslyDisableSanitizers: ['script', 'innerHTML'],

yii2: How to integrate AdminBSB Theme

I'm using yii2 advanced framework. And I am using AdminBSB theme for my layout. But this error appears. I tried on searching for same issues. But I can't figure it out. Here is the error when I inspect:
Uncaught TypeError: jQuery(...).yiiActiveForm is not a function
at HTMLDocument.
Some say I declare JS twice. But I didn't declare it twice or I didn't notice It call twice because of my template.
Below is how I am loading the javascript in my Asset Manager file.
public $js = [
"plugins/jquery/jquery.min.js",
"plugins/bootstrap/js/bootstrap.js",
"plugins/bootstrap-select/js/bootstrap-select.js",
"plugins/jquery-slimscroll/jquery.slimscroll.js",
"plugins/node-waves/waves.js",
"plugins/flot-charts/jquery.flot.js",
"plugins/jquery-sparkline/jquery.sparkline.js",
"js/admin.js"
];
i had the same theme and i also faced this error and that is because the yiiActiveForm is loaded before the jquery file does, even if you will fix that it will get in conflict with bootstrap js file that functions for the dropdown in the dashboard under user image. I advise you to change the loading of jquery and bootstrap to the following, you need to make some changes to you AppAsset.php file.
1.Remove the bootstrap and jquery links from the $js and $css arrays in the AppAsset.php.
2.Update your $depends array to the following.
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
'yii\bootstrap\BootstrapPluginAsset',
];
3.Then update your frontend/config/main.php to the following.
'assetManager' => [
'bundles' => [
'yii\web\JqueryAsset' => [
'sourcePath' => null, 'js' => ['//code.jquery.com/jquery-2.2.4.min.js'],
],
'yii\bootstrap\BootstrapAsset' => [
'sourcePath' => null, 'css' => ['//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'],
],
'yii\bootstrap\BootstrapPluginAsset' => [
'sourcePath' => null, 'js' => ['//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js'],
],
],
],

Yii2 loading Jquery in the head of the page

In my Yii2 application i've a script that need Jquery to be loaded in the head of the page.
I know there's a parameter that can be setted inside AppAssets.php :
public $jsOptions = [
'position' => \yii\web\View::POS_HEAD
];
but this will render all the Javascripts Files on the head of the page.
Is possibile to load only Jquery on the head?
Thanks in advance for all the help
You could simply do this in your view, e.g. :
$this->registerAssetBundle(yii\web\JqueryAsset::className(), View::POS_HEAD);
Or if you want to do this for all your page, you could customize JqueryAsset in your components configuration :
'components' => [
'assetManager' => [
'bundles' => [
'yii\web\JqueryAsset' => [
'jsOptions' => [ 'position' => \yii\web\View::POS_HEAD ],
],
],
],
],
Read more about Customizing Asset Bundles.

Categories

Resources