slim framework 3, fail to render html page - twig

Am using twig-view to render the html, currently am unable to change the Content type returned to the browser, i can see that content type returned by slim as json instead of html content hence all codes are displayed in browser
$app->get('/',function(Request $req,Response $res,array $args) use ($app){
$container = $app->getContainer();
$container->view->render($res, 'test.html',[]);
});
enter image description here

Try to return the response like this:
return $container->view->render($res, 'test.html', []);

Addition to Zamrony P. Juhara
i have found that middleware i put was editing response to be returned as json content
->withHeader("Content-Type", "application/json")
/*
CORS
*/
$app->add(function ($req, $res, $next) {
$response = $next($req, $res);
return $response
//->withHeader("Content-Type", "application/json")
//->withHeader('Access-Control-Allow-Origin', 'http://localhost:2222/')
->withHeader('Access-Control-Allow-Origin', '*')
->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
->withHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,PATCH,OPTIONS');
});
so the browser was only getting json content response hence it was dumping all codes as json content instead of Content-Type: "text/html",
and that solved my problem

Related

Set response header along with a string

I am trying to send the token in the headers of an HTTP request from backend to the frontend along with sending my own defined string. However, I am getting an issue. The token is being printed as null on the client-side. I don't know why:
Here's my code:
Node/Express
if (bcrypt.compareSync(passcode, results[0].password))
{
const token = jwt.sign({id: email}, secret, {expiresIn: 86400 });
console.log(token);
if(results[0].userrights == 'full')
{
res.setHeader('x-access-token', token);
res.send("Full Authorization");
}
//rest of the code
}
Angular
this.http.post('http://localhost:3000/api/login', form.value, {responseType: "text", observe:
'response'})
.subscribe(responseData => {
console.log(responseData);
console.log(responseData.headers.get('x-access-token')); //prints null on the console
I have searched quite a bit and found different examples which is making it very confusing. I don't want to use response status rather my own defined string. I have tried different things to print the variable but it still is throwing as null.
If you are using a browser extension to allow CORS requests then Access-Control-Expose-Headers should be added to the headers on server side. Please try adding the following line: res.setHeader('Access-Control-Expose-Headers', '*')
Angular2 's Http.post is not returning headers in the response of a POST method invocation
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers

express js set request header Content-Type in middleware based on file extension?

The end points of my API-application render data based on the request mime type. I have implementing express' response.format() to distinguish between the req types.
However, the handler also needs to be able to distinguish the formats based on the file extension like
/route/users.json
Express' response.format doesn't handle that case.
Therefore I was hoping I could simply use a middleware function and set the headers Content-Type according to the extension like this:
app.use('/', (req, res, next) => {
let contentType;
if (req.path.match(/\.json/)) {
contentType = 'application/json';
} else if (req.path.match(/\.xml/)) {
contentType = 'text/xml';
}
if (contentType) {
req.headers['Content-Type'] = contentType;
}
next();
});
But that's not working. I have checked whether the middleware is actually executed and that's the case. However the Content-Type does not persist.
So when the actual request handler is being executed the Content-Type is missing.
What am I doing wrong here?
So, the non-persistent content content type wasn't the problem. In fact the content-type was there, but due to focussing on the wrong problem, I got quite confused.
Anyway, the real "problem" was, that the header mime type was not available in the request header's accept field.
If that's not set express and any other sane web server won't recognize it.
Here's what I neede to do:
module.exports = function fileExtensionHeader(req, res, next) {
let contentType;
if (req.path.match(/\.json/)) {
contentType = 'application/json';
} else if (req.path.match(/\.xml/)) {
contentType = 'text/xml';
}
if (contentType) {
req.headers['Content-Type'] = contentType;
req.headers.accept = `${contentType},${req.headers.accept}`; // this line did the trick
}
next();
};
A word of warning:
This creates a potential security risk. The mime type should only be set by the request header sent by the browser.
No one should ever allow to set the mime type by file extension without a good reason.

Nodejs res.end() [and other versions of sending response like res.write() etc] not sending complete string, breaking in between

Scenario
I am creating a nodejs server, which'll act as a middle server between the actual client and actual server. i.e. I send a request to a website, through my nodejs server, receive the response from actual (website) server, and forward the same to the client (the browser).
Here's part of the code for doing that
const cheerio = require('cheerio');
//#================================================================
// include other files and declare variables
//#================================================================
app.get('/*', (req, res) => {
//#================================================================
// some code...
//#================================================================
request(options, function(error, response, body){
if (!error && response.statusCode == 200) {
res.writeHead(200, headers);
if (String(response.headers['content-type']).indexOf('text/html') !== -1){
var $ = cheerio.load(body);
//#================================================
// perform html manipulations
//#================================================
//send the html content as response
res.end($.html());
}else{
res.end(body);
}
}else{
res.send({status: 500, error: error});
}
});
}
Everything works fine, untill I stumble upon this particular website https://www.voonik.com/recommendations/bright-cotton-a-line-kurta-for-women-blue-printed-bcown-007b-38-1f2073ca.
If you look at its view source it is more or less like this
<!doctype html>
<html lang="en-in" data-reactid=".mc12nbyapk" data-react-checksum="-2121099716">
<!-- rest of the html code -->
...
<script type="text/javascript" charset="UTF-8" data-reactid=".mc12nbyapk.1.1">
window.NREUM||(NREUM={});NREUM.info = {"agent":"","beacon":"bam.nr-data.net","errorBeacon":"bam.nr-data.net"...
...
</script></body></html>
and when I send this very html in my response object, it sends incomplete html i.e. breaks in between somewhere of the last script tag.
I consoled log the html also and it prints the whole string. But sending the same in response object sends half.
Also tried res.write(); res.send() and storing the html content in a variable then sending that variable, but the outcome is same i.e. incomplete html content.
I was thinking of solution which wouldn't involve writing to and reading from a file. Just directly send the response as you receive it
after you manipulate the target server response contents, the content length is changed, so you must recalculate the content length and rewrite the content-length header, or just delete the content-length header,
put this code delete headers['content-length'], before res.writeHead(200, headers); this line.

Parse JSON from body when header is wrongly set

I'm using express.js to receive a JSON from a server that wrongly set the encoded header as urlencoded.
Content-Type: application/x-www-form-urlencoded\r\n
As I try to parse it I get different errors, such as "TypeError: Cannot convert object to primitive value".
If I send the JSON using postman with the correct header it works flawlessly.
How can I parse this JSON?
I wouldn't use body-parser.
If you do, it will try to decode your body according to the http headers.
Instead, you could write your own middleware, which can be something similar to this:
app.use((req, res, next) => {
req.body = JSON.parse(req.read());
next();
})

Chrome extensions - Other ways to read response bodies than chrome.devtools.network?

I'd like to read (not modify) the response body for all requests that match some pattern in a Chrome extension. I'm currently using chrome.devtools.network.onRequestFinished, which gives you a Request object with a getContent() method. This works just fine, but of course requires the devtools to be open for the extension to work. Ideally the extension would be a popup, but chrome.webRequest.onCompleted doesn't seem to give access to the response body. There is a feature request to allow the webRequest API to edit response bodies - but can webRequest even read them? If not, is there any other way to read response bodies outside of devtools extensions?
The feature request you linked to implies that there is no support for reading either:
Unfortunately, this request is not trivial. (...) Regarding reading the Response Body: This is challenging from a performance perspective. (...) So overall, this is just not easy to achieve...
So, no, there doesn't seem to be a way for an extension to access network response bodies, except for devtools.
Here is what I did
I used the chrome.webRequest & requestBody to get the post requests body
I used a decoder the parse the body into a string
Here is an example
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
if(details.method == "POST")
// Use this to decode the body of your post
var postedString = decodeURIComponent(String.fromCharCode.apply(null,
new Uint8Array(details.requestBody.raw[0].bytes)));
console.log(postedString)
},
{urls: ["<all_urls>"]},
["blocking", "requestBody"]
);
If you have the this pattern of requests you can run something like that in your background.html file:
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://example.com/" + yourStringForPattern, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var body = xhr.responseText;
// call some function to do something with the html body
}
}
xhr.send();

Resources