I am unable to get images loaded on a webpage when in the LocalState directory.
Specifically, there appears to be a security issue when attempting to launch the webpage when the file path is referencing the LocalState directory.
The webpage DOES load with images when I right-click the html file and view it in the browser within Visual Studio.
I have changed the path of the src tag to: src="ms-appdata:///Local/Logo.jpeg"
It doesn't work.
Help me...
Example code
public static async Task Update(WebView webview, IStorageFile file) {
var html = await Windows.Storage.PathIO.ReadTextAsync(file.Path);
webview.NavigateToString(html);
}
The NavigateToString method doesn't work with tags that point to images in the LocalData folder. (as far as I recall anyway). In fact NavigateToString also breaks JavaScript and CSS links.
Images on Server
One solution, is to change your source to point to a network server instead of localdata. I'm not sure it that works for your app scenario though.
Images and HTML as content
The second choice is to add your html and image files as content to your app and use
WebView1.Navigate(new Uri("ms-appx-web:///assets/SampleHtmlPage.html"));
to load the HTML.
In Process HTTP Server
Here is a solution that uses a custom HTTP server in the app to handle the issues.
Loading Local HTML Content in Metro WebView (Windows 8)
Base 64 encoded image
Finally, there is another solution using Base64 encoding of your images in the LocalData folder.
internal async void MakeHtmlString()
{
StorageFile imageFile; // get image file here.
var html =
string.Format("<div><img src='data:image/png;base64,{0}'",
await GetImageBase64(imageFile));
}
internal async Task<string> GetImageBase64(StorageFile imageFile)
{
var imageStream = await imageFile.OpenAsync(FileAccessMode.Read);
var inputStream = imageStream.GetInputStreamAt(0);
var dataReader = new DataReader(inputStream);
var dataResults = await dataReader.LoadAsync((uint)imageStream.Size);
var bytes = new byte[dataResults];
dataReader.ReadBytes(bytes);
return Convert.ToBase64String(bytes);
}
This last approach works for images, but not for CSS files.
Related
I want to embed an Emscripten graphical application to a Vue SPA. The output of Emscripten is a .js and a .wasm file. I cannot get rid of the javascript file and write my own because it contains the proxy for the glfw API which I'm using for input handling.
I can load the javascript (with WASM) successfully with the following code:
This code injects a new <script> tag to the DOM and loads the javascript file.
injectScript(source) {
let script = document.createElement('script');
script.type = 'text/javascript';
script.src = source;
document.head.appendChild(script);
document.head.removeChild(script);
}
// During mount
injectScript("xy.js")
I have a similar method that creates the global Module object for Emscripten using the DOM:
// template
<canvas id="canvas">
// During mount
injectCode(`
var canvas = document.getElementById('canvas');
var Module = {
canvas: canvas,
};
`);
This method works when I open the page for the first time. Since we are talking about a single page application the javascript context is kept and the same code fails to create the wasm context for the second time when I reopen the page.
I'm also interested in completely different solutions but I would like to keep glfw for input handling in the graphics code.
According to the Emscripten documentation the Module object supposed to have a destroy() method. I would try to call It when the Vue component unmounted but mine doesn't have It.
Tried to null the Module object during unmount and It didn't work.
I am trying to serve a static HTML file using the res.sendFile() method from my express.js server that is hosted on AWS Lambda using the Serverless framework. Assuming that I am trying to serve an HTML file from the directory src/views/users/index.html.
In deployment, this is the file path that I have tried to serve my HTML file from /var/task/src/views/users/vindex.html, but I keep getting the error Error: ENOENT: no such file or directory, stat '/var/task/src/views/users/index.html' when viewing the AWS Cloudwatch log.
app.use(express.static(__dirname));
path.resolve(__dirname, "./src/views/users/index.html");
This is the results I get when I run tree src locally:
Have anyone experienced this issue before, and have solved it? Thank you so much!
Well, after many grueling hours and trying many solutions, I have found a workaround to render the html content without actually needing to render a .html file.
I ended up making a helper method that returns a string of the html content and send the html content string using the res.send() method instead.
html helper function
export const htmlHelper = () => {
return `<html content goes here>`;
}
route method
app.get('/html', (_, res) => {
const htmlString = htmlHelper();
return res.send(htmlString);
})
I am using the printing package in flutter: https://pub.dev/packages/printing
The documentation shows how to create PDFs from scratch. I already have a PDF at a URL. Is there a way to retrieve it and print it with the package? Or is there an alternate method with another package?
I have tried the following ways to achieve the printing feature:
Directly get the remote data bytes
With the popular package printing
var data = await http.get(url);
await Printing.layoutPdf(onLayout: (_) => data.bodyBytes);
But I found that this way will have the printing area disorder issue when printing a roller size paper (POS printer)
Sharing (alternative of the first one)
Use the sharePdf function
var data = await http.get(url);
await Printing.sharePdf(bytes: data.bodyBytes, filename: 'my-document.pdf');
This one needs an additional step to print (click the 'functions' icon of browser then print)
View it from the browser and print it natively
Check out this package url_launcher
import 'package:url_launcher/url_launcher.dart';
if (await canLaunch(url)) {
await launch(url);
}
This one needs an additional step to print (click the 'functions' icon of browser then print)
Download the remote file and save it, use the flutter_pdf_printer package.
Use this package flutter_pdf_printer and path_provider
var data = await http.get(url);
final output = await getTemporaryDirectory();
final file = File('${output.path}/your_file_name_${new DateTime.now().microsecondsSinceEpoch}.pdf');
await file.writeAsBytes(data.bodyBytes);
await FlutterPdfPrinter.printFile(file.path);
*** this package will have channel registrant issue, please run flutter clean after installation ***
This package is a little bit outdated, but it works for me to print with a roller 80 size pdf. It uses the Swift UIKit package, which has good compatibility.
Summary
My scenario is to print a roller 80 size pdf with infinite height, the printing package doesn't work for cuz it cannot preview the pdf properly. So I changed to the last way to print, which works for me. If you just print an A4 or a regular size PDF, the printing package is still a good choice.
From the plugin documentation To save the pdf file using the path_provider library:
final output = await getTemporaryDirectory();
final file = File("${output.path}/example.pdf");
await file.writeAsBytes(pdf.save());
print the document using the iOS or Android print service
await Printing.layoutPdf(
onLayout: (PdfPageFormat format) async => pdf.save());
Convert your string url to URI, please make sure you are adding http
http: ^0.13.4
import 'package:http/http.dart' as http;
Uri uri = Uri.parse('Your link here');
http.Response response = await http.get(uri);
var pdfData = response.bodyBytes;
await Printing.layoutPdf(onLayout: (PdfPageFormat
format) async => pdfData);
Given this link:
Test
Which is an HTML page in Shared folder as shown in the href attribute. Shouldn't MVC be able to find this in the Shared folder?
When I click on the link I get a 404 error.
Found the solution and am posting for others benefit...
MVC routing is wired up out-of-the-box to NOT handle inbound .HTML requests. So why fight it?
Create an action method that looks like this:
public ActionResult GetHTMLFile(string filename)
{
var dir = "/Views/HTML/";
var suffix = ".html";
var path = dir + filename + suffix;
return new FilePathResult(path, "text/html");
}
This tells us that we have a Views folder and a subfolder named HTML where we store all of our HTML files and ensure the suffix is always html. VS does this by default when you add new HTML files. This method is "building" the full path to the HTML file. It then uses FilePathResult to return the content.
Use the ActionLink helper because you can easily configure the action method name as well as the controller name if you need it...
#ActionLink("Layout File changes", "GetHTMLFile", new {filename="_Layout"})
We are "Tricking" MVC by only passing part of the file name (without the extension and without the actual path). The controller get's the string and serves up the HTML for us.
I am trying to compile and render a Dust template in Express using content from two different sources:
Dust files located under the /views directory
A response as a string from an external CDN
My goal is to receive a string response from the CDN, which will have content referencing the Dust files stored locally in /views. It will look something like this:
"{>layout/}
{<content}
<h1>Here is the dynamic content that will change based on the CDN request</h1>
{<content}"
The layout.dust file is stored locally under /views, which is referenced from the CDN's string response.
I am trying to compile the string response in my route by doing:
var compiled = dust.compile(templateStr, 'catalog_template');
dust.loadSource(compiled);
dust.render('catalog_template', dustParams, function(err, out) {
if(err) {
console.log(err);
}
console.log(out);
res.render(out);
});
But rendering the file causes an error:
[Error: Template Not Found: layout]
So somehow I need to compile the CDN's string with layout.dust (which is located in my /views directory). What is the best way to do this?
You just need to compile layout.dust by itself and when you render the CDN template, dust will pull in the layout partial. You can have dust dynamically compile templates from your filesystem like so:
dust.onLoad = function (name, callback) {
// Get src from filesystem
fs.readFile('path to template', function (err, data) {
if (err) throw err;
callback(err, data.toString());
});
}
Make sure you require the node fs module in your code.